在 switch 之外访问 swift enum case?
access swift enum case outside of switch?
假设我有一个简单的 Pet 枚举:
enum Pet {
case dog(name:String)
case cat(name:String)
var name:String {
switch self {
case .dog(let name):
return name
case .cat(let name):
return name
}
}
}
(它们具有相同类型的关联值,因此感觉多余的事实应该被忽略)
现在我希望能够等同于宠物。我可以写:
extension Pet:Equatable { }
func == (a:Pet, b:Pet) -> Bool {
return a.name == b.name
}
但这将允许一只名为 "Spots" 的猫等于一只名为 "Spots" 的狗。这个我不要有没有一种简单的方法来访问枚举实例的大小写?我们通常在 switch 语句中执行它们,但在这种情况下,我想要更直接的东西(一行),毕竟我可能需要在未来的 Comparable 扩展中使用它。
我可以自己做:
extension Pet {
var petType:Int {
switch self {
case .dog:
return 1
case .cat:
return 2
}
}
}
现在我可以将 ==
实现更改为
func == (a:Pet, b:Pet) -> Bool {
return a.petType == b.petType && a.name == b.name
}
是否有一些内置的 Swift 语法糖可以为我做同样的事情?我试过 type(of:)
,但那只是 returns 宠物,与实例案例无关。
你可以这样做:
func ==(lhs: Pet, rhs: Pet) -> Bool {
if case let Pet.cat(l) = lhs, case let Pet.cat(r) = rhs where l == r { return true }
if case let Pet.dog(l) = lhs, case let Pet.dog(r) = rhs where l == r { return true }
return false
}
但是 switch
可能看起来更好,而且绝对更容易维护。
据我所知,Swift 没有为我们提供仅检索案例标签的快捷方式。
在你的情况下,你可以利用你的 name
属性:
写这样的东西
extension Pet: Equatable {
static func == (a: Pet, b: Pet) -> Bool {
switch (a, b) {
case (.dog, .dog), (.cat, .cat):
return a.name == b.name
default:
return false
}
}
}
如果你的Pet
没有name
属性,你可以写成:
extension Pet: Equatable {
static func == (a: Pet, b: Pet) -> Bool {
switch (a, b) {
case let (.dog(namea), .dog(nameb)),
let (.cat(namea), .cat(nameb)):
return namea == nameb
default:
return false
}
}
}
但在您的情况下,使用 class 层次结构不是很自然吗?:
class Pet {
var name: String
init(name: String) {
self.name = name
}
}
class Dog: Pet {}
class Cat: Pet {}
extension Pet {
static func dog(name: String) -> Pet {
return Dog(name: name)
}
static func cat(name: String) -> Pet {
return Cat(name: name)
}
}
extension Pet: Equatable {
static func == (a: Pet, b: Pet) -> Bool {
return type(of: a) === type(of: b) && a.name == b.name
}
}
我有一种混合方法,可以使事情更加模块化:
enum Pet {
case dog(name:String)
case cat(name:String)
var name: String {
switch self {
case .dog(let name):
return name
case .cat(let name):
return name
}
}
func equalCaseTo(otherPet: Pet) -> Bool {
switch (self, otherPet) {
case (.dog(_), .dog(_)), (.cat(_), .cat(_)):
return true
default:
return false
}
}
func equalNameTo(otherPet: Pet) -> Bool {
return name == otherPet.name
}
}
func ==(left:Pet, right:Pet) -> Bool {
return left.equalCaseTo(right) && left.equalNameTo(right)
}
假设我有一个简单的 Pet 枚举:
enum Pet {
case dog(name:String)
case cat(name:String)
var name:String {
switch self {
case .dog(let name):
return name
case .cat(let name):
return name
}
}
}
(它们具有相同类型的关联值,因此感觉多余的事实应该被忽略)
现在我希望能够等同于宠物。我可以写:
extension Pet:Equatable { }
func == (a:Pet, b:Pet) -> Bool {
return a.name == b.name
}
但这将允许一只名为 "Spots" 的猫等于一只名为 "Spots" 的狗。这个我不要有没有一种简单的方法来访问枚举实例的大小写?我们通常在 switch 语句中执行它们,但在这种情况下,我想要更直接的东西(一行),毕竟我可能需要在未来的 Comparable 扩展中使用它。
我可以自己做:
extension Pet {
var petType:Int {
switch self {
case .dog:
return 1
case .cat:
return 2
}
}
}
现在我可以将 ==
实现更改为
func == (a:Pet, b:Pet) -> Bool {
return a.petType == b.petType && a.name == b.name
}
是否有一些内置的 Swift 语法糖可以为我做同样的事情?我试过 type(of:)
,但那只是 returns 宠物,与实例案例无关。
你可以这样做:
func ==(lhs: Pet, rhs: Pet) -> Bool {
if case let Pet.cat(l) = lhs, case let Pet.cat(r) = rhs where l == r { return true }
if case let Pet.dog(l) = lhs, case let Pet.dog(r) = rhs where l == r { return true }
return false
}
但是 switch
可能看起来更好,而且绝对更容易维护。
据我所知,Swift 没有为我们提供仅检索案例标签的快捷方式。
在你的情况下,你可以利用你的 name
属性:
extension Pet: Equatable {
static func == (a: Pet, b: Pet) -> Bool {
switch (a, b) {
case (.dog, .dog), (.cat, .cat):
return a.name == b.name
default:
return false
}
}
}
如果你的Pet
没有name
属性,你可以写成:
extension Pet: Equatable {
static func == (a: Pet, b: Pet) -> Bool {
switch (a, b) {
case let (.dog(namea), .dog(nameb)),
let (.cat(namea), .cat(nameb)):
return namea == nameb
default:
return false
}
}
}
但在您的情况下,使用 class 层次结构不是很自然吗?:
class Pet {
var name: String
init(name: String) {
self.name = name
}
}
class Dog: Pet {}
class Cat: Pet {}
extension Pet {
static func dog(name: String) -> Pet {
return Dog(name: name)
}
static func cat(name: String) -> Pet {
return Cat(name: name)
}
}
extension Pet: Equatable {
static func == (a: Pet, b: Pet) -> Bool {
return type(of: a) === type(of: b) && a.name == b.name
}
}
我有一种混合方法,可以使事情更加模块化:
enum Pet {
case dog(name:String)
case cat(name:String)
var name: String {
switch self {
case .dog(let name):
return name
case .cat(let name):
return name
}
}
func equalCaseTo(otherPet: Pet) -> Bool {
switch (self, otherPet) {
case (.dog(_), .dog(_)), (.cat(_), .cat(_)):
return true
default:
return false
}
}
func equalNameTo(otherPet: Pet) -> Bool {
return name == otherPet.name
}
}
func ==(left:Pet, right:Pet) -> Bool {
return left.equalCaseTo(right) && left.equalNameTo(right)
}