Non Blocking Channel Operations in Swift
import Foundation
let messages = DispatchQueue(label: "messages")
let signals = DispatchQueue(label: "signals")
// Here's a non-blocking receive. If a value is
// available on `messages` then the `messages.sync` block
// will execute. If not, it will immediately take the `else` case.
if messages.sync(execute: { () -> String? in
// Simulating a non-blocking receive
return nil
}) != nil {
print("received message")
} else {
print("no message received")
}
// A non-blocking send works similarly. Here `msg`
// cannot be sent to the `messages` queue, because
// there is no receiver. Therefore the `else` case is selected.
let msg = "hi"
if messages.sync(execute: { () -> Bool in
// Simulating a non-blocking send
return false
}) {
print("sent message", msg)
} else {
print("no message sent")
}
// We can use multiple conditions to implement a multi-way
// non-blocking select. Here we attempt non-blocking receives
// on both `messages` and `signals`.
if let message = messages.sync(execute: { () -> String? in
// Simulating a non-blocking receive
return nil
}) {
print("received message", message)
} else if let signal = signals.sync(execute: { () -> Bool? in
// Simulating a non-blocking receive
return nil
}) {
print("received signal", signal)
} else {
print("no activity")
}
This Swift code demonstrates non-blocking operations similar to the original example. However, Swift doesn’t have built-in channels or a select
statement like Go does. Instead, we use DispatchQueue
to simulate similar behavior.
In this example:
We create two
DispatchQueue
instances to represent our channels.For non-blocking receives, we use
sync
on the queue and returnnil
to simulate an empty channel. If a value is returned, it’s treated as a successful receive.For non-blocking sends, we use
sync
on the queue and returnfalse
to simulate a failed send. Returningtrue
would indicate a successful send.The multi-way select is simulated using multiple
if-else
conditions, each trying to receive from a different queue.
To run this program:
$ swift non-blocking-operations.swift
no message received
no message sent
no activity
This example demonstrates how to perform non-blocking operations in Swift, although the exact semantics differ from Go’s channels. In real-world Swift applications, you might use more sophisticated concurrency primitives like OperationQueue
, DispatchGroup
, or the new structured concurrency features introduced in Swift 5.5.