Swift 开关盒中的静态变量
Swift static var in switch case
switch-case
用于比较 static var
s 未按预期工作。但是,指定类型或直接比较是可行的。请看下面:
class AnimalHelper {
func loadAnimal(_ animal: Animal) {
// Doesn't compile
switch animal {
case .squirrel, .deer: loadGrass()
case .dolphin: return // not implemented
default: loadMeat()
}
// Direct comparison works
if animal == .squirrel || animal == .deer {
loadGrass()
} else if animal == .dolphin {
return // not implemented
} else {
loadMeat()
}
// Specifying the type explicitly also works
switch animal {
case Animal.squirrel, Animal.deer: loadGrass()
case Animal.dolphin: return // not implemented
default: loadMeat()
}
}
func loadGrass() {}
func loadMeat() {}
}
class Animal {
let id = 6 // Will be generated
let hasFourLegs = true
let numberOfEyes = 2
// ... //
static var squirrel: Animal { return .init() }
static var dolphin: Animal { return .init() }
static var puma: Animal { return .init() }
static var deer: Animal { return .init() }
}
extension Animal: Equatable {
public static func ==(lhs: Animal, rhs: Animal) -> Bool {
return lhs.id == rhs.id
}
}
我确定上面的某些内容不太正确,因为我收到以下编译错误:
Enum case 'squirrel' not found in type 'Animal'
Enum case 'deer' not found in type 'Animal'
Enum case 'dolphin' not found in type 'Animal'
请告诉我在 switch-case
条件下检查相等性与在 if
条件下检查相等性有何不同。
在 Swift 中,switch-case
可以使用几种不同的规则来匹配 switch
值和 case
标签:
enum
大小写匹配
在这种情况下,您可以使用点引导的大小写标签,但不幸的是,您的 Animal
不是 enum
。
(这与下面的 equality 不同,因为 enum
个案例可能具有关联值。)
模式匹配运算符~=
Swift 搜索 switch
值类型和 case
标签类型的重载,如果找到,则应用运算符并使用 Bool
结果表示 匹配 。
为此,Swift 需要独立于 switch
- 值推断 case
- 标签的类型,因此 Swift 无法推断 case
- 的类型带点符号的标签。
平等==
当 switch
值为 Equatable
时,Swift 使用相等运算符 ==
将 switch
值与 case
-标签。
(可能还有很多想不起来了)
详细的行为没有明确定义,但编译器很难解决两个规则——模式匹配和相等。 (您可能希望使用 ~=
为 Equatable
类型定义自定义匹配。)
因此,在 Swift 3 中,case
标签中的点引导符号仅适用于 enum
类型。
但是,据我检查,Swift 4 人成功了。试试 Xcode 9(目前最新的是 beta 3),你的代码就会编译。此行为可能会在 Xcode 9 的发行版中发生变化,但您知道如何解决。
switch-case
用于比较 static var
s 未按预期工作。但是,指定类型或直接比较是可行的。请看下面:
class AnimalHelper {
func loadAnimal(_ animal: Animal) {
// Doesn't compile
switch animal {
case .squirrel, .deer: loadGrass()
case .dolphin: return // not implemented
default: loadMeat()
}
// Direct comparison works
if animal == .squirrel || animal == .deer {
loadGrass()
} else if animal == .dolphin {
return // not implemented
} else {
loadMeat()
}
// Specifying the type explicitly also works
switch animal {
case Animal.squirrel, Animal.deer: loadGrass()
case Animal.dolphin: return // not implemented
default: loadMeat()
}
}
func loadGrass() {}
func loadMeat() {}
}
class Animal {
let id = 6 // Will be generated
let hasFourLegs = true
let numberOfEyes = 2
// ... //
static var squirrel: Animal { return .init() }
static var dolphin: Animal { return .init() }
static var puma: Animal { return .init() }
static var deer: Animal { return .init() }
}
extension Animal: Equatable {
public static func ==(lhs: Animal, rhs: Animal) -> Bool {
return lhs.id == rhs.id
}
}
我确定上面的某些内容不太正确,因为我收到以下编译错误:
Enum case 'squirrel' not found in type 'Animal'
Enum case 'deer' not found in type 'Animal'
Enum case 'dolphin' not found in type 'Animal'
请告诉我在 switch-case
条件下检查相等性与在 if
条件下检查相等性有何不同。
在 Swift 中,switch-case
可以使用几种不同的规则来匹配 switch
值和 case
标签:
enum
大小写匹配在这种情况下,您可以使用点引导的大小写标签,但不幸的是,您的
Animal
不是enum
。(这与下面的 equality 不同,因为
enum
个案例可能具有关联值。)模式匹配运算符
~=
Swift 搜索
switch
值类型和case
标签类型的重载,如果找到,则应用运算符并使用Bool
结果表示 匹配 。 为此,Swift 需要独立于switch
- 值推断case
- 标签的类型,因此 Swift 无法推断case
- 的类型带点符号的标签。平等
==
当
switch
值为Equatable
时,Swift 使用相等运算符==
将switch
值与case
-标签。
(可能还有很多想不起来了)
详细的行为没有明确定义,但编译器很难解决两个规则——模式匹配和相等。 (您可能希望使用 ~=
为 Equatable
类型定义自定义匹配。)
因此,在 Swift 3 中,case
标签中的点引导符号仅适用于 enum
类型。
但是,据我检查,Swift 4 人成功了。试试 Xcode 9(目前最新的是 beta 3),你的代码就会编译。此行为可能会在 Xcode 9 的发行版中发生变化,但您知道如何解决。