Swift compilation time with nil coalescing operator
I'm almost certain that this has to do with type inference. When interpreting all of those +
and ??
operators the compiler is doing a lot of work behind the scenes to infer the types of those arguments. There are around thirty overloads for the +
operator alone and when you chain several of them together you are making the compiler's job much more complicated than you might think.
Why does nil-coalescing compile faster with string interpolation than when used in expressions?
Most likely the problem is the +
operator. The operator is heavily overloaded (e.g. for numbers) therefore there are multiple possible types. My guess is that ??
does not make much difference there, only to make the expression more complicated and therefore harder to evaluate.
Also note that there are multiple bugs reported for this, for example SR-2877 or SR-1107 (for integers).
Historically, there were also bugs related to ??
but I think many of them have been already fixed.
Swift: compile-time error with optional chaining and nil-coalescing
Type inferring is hard with complicated expressions. That [_]
usually means that type is unknown - could not be inferred. Simplifying the expression solves the problem in 99% of the time:
class A<T> {
var val: T
var x: A<T>?
var y: A<T>?
init(t:T){
val = t
}
func test() -> [T] {
let xResult = self.x?.test() ?? []
let yResult = self.y?.test() ?? []
return xResult + [val] + yResult
}
}
Another 99% of the time, type inferring problems can be solved by specifying a type explicitly:
return (self.x?.test() as [T]? ?? []) + [val] + (self.y?.test() ?? [])
You have found a workaround yourself. That workaround with parenthesis removes certain number of type inferring paths.
Reported as SR-4309
Xcode 13.3 Compiler Bug with multiple nil coalescing operators?
Received feedback on FB10005210 from Apple today, resolved with Xcode 14 Beta 3, Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) /p>
Swift addition does not work if it's placed after Nil-Coalescing operator
Upon confirmation, I am now satisfied that it's due to + having higher precedence over ??. Putting code inside () did the trick for me to control the precedence in calculation
What is the role of the nil-coalescing operator ?? in optional chaining?
That's not the nil-coalescing operator you are seeing. The nil-coalescing operator is a binary operator, that needs to be placed between an Optional value and a non-Optional one or two Optional values. In your code example, that's clearly not the case.
What you are seeing is optional chaining on a nested-Optional.
let nestedOptional: Int?? = nil
nestedOptional??.description
You can create Optional values whose wrapped value is also an Optional, in which case you need to unwrap each optional layer one-by-one.
Nil coalescing operator in swift returns a weird result
There's a lot going on here:
a
overflows, becaue128
is larger than the maximum value that can be stored in anInt8
(Int8.max
=127
), thus it'll returnnil
.This
nil
, a.k.a.Optional.None
is of typeOptional<Int8>
is not the type specified by the type annotation ofa
(Int8??
, a.k.a.Optional<Optional<Int8>>
), so it's wrapped in another optional, becomingOptional.Some(Optional.None)
, which is now the correct type.nilCoalescing()
doesn't return anything. (Which actually means it returns()
, a.k.a.Void
)Don't do this explicit
nil
check and force unwrap (!
):a != nil ? a! : b
. Use??
instead:a ?? b
What exactly are you trying to do here?
Compiler not understanding Nil Coalescing Operator on NSTimeInterval
Your problem is probably elsewhere. This runs just fine:
func optional() -> NSTimeInterval? {
return nil
}
func nonOptional() -> NSTimeInterval {
return 145
}
let duration = optional()
let time = duration ?? nonOptional()
print(time)
Perhaps post some more of the surrounding code?
Nil coalescing operator for dictionary
Trying use like yours give you and error :
Left side of mutating operator has immutable type '[Int]?'
By putting parentheses it will be no compile error and it will work
var myDict = [String : [Int]]()
myDict["Algebra"]?.append(contentsOf: [98,78,83,92]) ?? (myDict["Algebra"] = [98,78,83,92])
print(myDict) // ["Algebra": [98, 78, 83, 92]]
Swift Documentation is here for Infix Operators.
Related Topics
Swift Vscode Class in Other File Not Recognized
Call Function When If Value in Nsuserdefaults.Standarduserdefaults() Changes
How to Make a Function Complete Before Calling Others in an Ibaction
Avcapturevideopreviewlayer Is Not Visible on The Screenshot
Use of Nspathcontrol to Represent Virtual Path
How to Pass a Class and Method to Create an Instance of a Class
How to Set iOS 13 Glyphs Programmatically
How to Load Nsview from Xib with Swift 3
Swift 3 Closure Overload Resolution
Fetching Child Sum from Core Data
Xcode 8 Swift 3 Pitch-Altering Sounds
Iwatch: Wkinterfacelabel How to Stop Text from Being Cut Off with "..." at The End of a Label
Firebase and Reading Nested Data Using Swift
Function Builder Not Working When Only One Value
Resulting Mtltexture Lighter Than Cgimage
Changing The Color of a Button in Swiftui on Tvos
Play Sound with a Little Delay
How to Hide the Back Button from the Status Bar on the Apple Watch