These two concepts are not equivalent.
In your Swift example, you're creating a variable of type String?
and assigning it the value of a string literal. In the Ruby example, you're assigning a string literal to your optionalString
variable if optionalString
is undefined, nil, or evaluates false (more info).
In Swift, when you create a variable of optional type, all you're doing is specifying that the variable is allowed to be nil, so a closer representation of your Ruby example might look like this:
var optionalString: String?
optionalString = optionalString ?? "This is optional"
Which uses Swift's nil coalescing operator and is equivalent to the following usage of the ternary conditional operator, where optionalString
is assigned the unwrapped value of optionalString
if it isn't nil, or a fallback value of "This is optional" if it isn't.
optionalString = optionalString != nil ? optionalString! : "This is optional"
Note that by doing this, your variable will still have an optional type and need to be unwrapped to be used, and since you're fallback value is a string literal that won't ever be nil, you can confidently forcibly unwrap the optional with the !
operator.
But even though this can be used to set a variable with a fallback value, it still isn't entirely the same as your Ruby example since all it's doing is checking the nilness of the variable, and not whether it evaluates false or is undefined.
In Swift, you can't test the falseness of variables by sticking them into conditions unless they are instances of a type that conforms to the BooleanType
protocol. This means that if you wanted to achieve something similar with a type that supports a falseness check, you could implement something like this:
var optionalBool: Bool? = false
optionalBool = optionalBool != nil ? (!optionalBool! ? true : optionalBool!) : true
Which will assign a fallback value of true
to the optionalBool
variable if the variable is either nil or evaluates to false
. (optionalBool
will still need to be unwrapped for most uses)
But this still leaves a difference with undefined variables, and as far as I know, there isn't any way to achieve the equivalence to Ruby's ||=
in this regard in Swift without inlining the nilness checks in the instantiation of a variable based on a fallback value and the value of some other variable.
var optionalString: String?
var nonOptionalString = optionalString ?? "This is not optional"
Note, there's no point in nonOptionalString
being optional here, since it will always have a value.