Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do two distinct array literals equal each other in Swift?

Tags:

swift

Why does the expression

import Foundation
["a", "b", "c"] == ["c", "b", "a"]

evaluate to true in a Swift playground?

(The expression evaluates to false when Foundation is not imported.)

like image 252
titaniumdecoy Avatar asked Dec 01 '25 06:12

titaniumdecoy


2 Answers

Josh's answer is close, but not quite right. Option-click on the equals operator. Your literals are Foundation.CharacterSets.

public static func == (lhs: CharacterSet, rhs: CharacterSet) -> Bool

For literal resolution, the compiler is going to search

  1. The module you're working in.
  2. Your imports.
  3. The Swift standard library. (Which has some special module-scope-disambiguation rule where implicitly-typed literals are Arrays, because that makes working with the language easier for the most part.)

enter image description here

Is this a bug of ambiguity? Yes. Is it resolvable? I doubt it. I bet it's broken because nobody has been able to get the performance to be good enough if it did an exhaustive search. But please, log a bug, find out, and report back!

Swift.Set conforms to ExpressibleByArrayLiteral and it appears that when you compare two ArrayLiterals the compiler does in fact choose to evaluate them as Set's. you can confirm that its true by doing this:

import Foundation
let a = ["a", "b", "c"]
let b = ["c", "b", "a"]

print(["a", "b", "c"] == ["c", "b", "a"])
print(["a", "b", "c"] as Set<String> == ["c", "b", "a"] as Set<String>)
print(["a", "b", "c"] as [String] == ["c", "b", "a"] as [String])
print(a == b)
true
true
false
false

TLDR if you don't annotate the type of an array literal the compiler is free to coerce the type to any type that it chooses to infer as long as it conforms to ExpressibleByArrayLiteral.

like image 26
Josh Homann Avatar answered Dec 04 '25 00:12

Josh Homann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!