这怎么可能是真的?
您也可以 在 bilibili 阅读此文。
1 | if a == 1 && a == 2 && a == 3 { |
这本来是个 JavaScript 的面试题,但这并不能阻止我们在推特上研究 Swift 里的解法。
All three match – how many ways can you think of to make this true in Swift? You’ll learn by trying 👍 pic.twitter.com/FTRh2uKhTb
— Paul Hudson (@twostraws) 2018年1月20日
本文不讨论 Unicode 或藏代码这些方法。
计算型变量
这可能是大家最容易想到的,只要每次自加一就好了:
1 | var _a = 0 |
重载运算符
参数名并不重要,所以本文采用统一的 lhs
和 rhs
当然除了改变量之外,改运算符也是一种思路:
1 | var a = 1 |
然后就出现了更简单粗暴的:
1 | func &&(lhs: Bool, rhs: Bool) -> Bool { return true } |
遵循新协议
这个有点反着来的感觉,确实不容易想到。我们可以让某种 Equatable
遵循 ExpressibleByIntegerLiteral
协议,这样 1、2、3 就能被视为和 a
是同一个类型的,我们也就可以欺骗已经存在的 ==
,让他们被视为相等的:
1 | enum Foo: ExpressibleByIntegerLiteral { |
或者我这个有点重现 C 语系感觉的:
1 | extension Bool: ExpressibleByIntegerLiteral { |
楼主中途又加了个限制,要求代码同时符合这个运行结果:
1 | if b == 1 && b == 2 && b == 3 { |
但这只要 a
和 b
不是同一个类型/实现就可以了,没啥影响。而且我们还可以用类似于这样的方法来掩人耳目:
1 | let a: Bool = 1, b = 1 |