Swift 中的某些重复枚举类型转换
Some duplicate enum type casting in Swift
查看以下代码:
enum Gender {
case Male, Female, Unknown
}
enum ExplicitGender {
case Male, Female
}
func whatGender(_ g: Gender) {
print("I am \(g)")
}
func makeSureYourGender() -> ExplicitGender {
return ExplicitGender.Male
}
var myGender = makeSureYourGender();
// How to Cast type `ExplicitGender` to `Gender`?
// This fails
// whatGender(myGender)
语法 myGender as ExplicitGender
不正确。
其实Male
,Female
在ExplicitGender
和Gender
中是一样的。
使 2 is 2 different Enum Types 不完全正确。
或者有另一种代码结构或语法来解决这个问题?
另请参阅:
enum Language {
case English, French, Arabic, Russian, Chinese, Spanish, Japanese, German, Italian
}
enum UNOfficialLanguage {
case English, French, Arabic, Russian, Chinese, Spanish
}
在 typescript 中,我将使用:
type UNOfficialLanguage = 'English' | 'French' | 'Arabic' | 'Russian' | 'Chinese' | 'Spanish';
type Language = UNOfficialLanguage | 'Japanese' | 'German' | 'Italian';
您不能(向下转换或向上转换)转换彼此不相关的对象。请查看 casting on swift 以获取有关如何投射的信息。
Gender 和 ExplicitGender 是互不相关的枚举。
一种解决方案是创建一个辅助函数,将 Gender 类型转换为 ExplicitGender 类型,反之亦然。请以下面的代码为例:
func genderFromExplicitGender(gender: ExplicitGender) -> Gender {
switch gender {
case .Male: return .Male
case .Female: return .Female
}
return .Unknown }
这里要注意的是,即使性别和明确性别有男性和女性。无论如何,它们彼此没有关系。上面的代码检查了男性(如 ExplicitGender.Male)和 returns 男性(如 Gender.Male),对女性也是如此。
我会建议您在 swift
中阅读更多关于铸造的内容
您的 TypeScript 示例不是枚举。它是字符串文字类型的联合。 Swift 中没有等同于文字类型的东西。 (TypeScript 也有枚举,但它们是不同的东西。)
Swift 和 TypeScript 对于类型的含义有着截然不同的方法。在 TypeScript 中,具有相同结构的两个事物是相同的类型(“结构类型”)。在 Swift 中,两个可以具有相同结构的事物可以是无关的,重要的是类型的名称(“名义类型”)。 TS方式方便,但是有很多类型它不能表达。 Swift方式可以表达更多的东西,但是缺少了一定的便利。
例如,在 TypeScript 中,如果您声明两个具有相同属性的接口,它们是可以互换的:
interface Animal {
legs: number;
}
interface AirTravel {
legs: number;
}
let trip: AirTravel = {legs: 4};
function feedAnimal(a: Animal) {}
feedAnimal(trip) // No problem... legs are legs
Swift中的等效代码会报错:
struct Animal {
var legs: Int
}
struct AirTravel {
var legs: Int
}
let trip = AirTravel(legs: 4)
func feedAnimal(_ a: Animal) {}
feedAnimal(trip)
// error: cannot convert value of type 'AirTravel' to expected argument type 'Animal'
您是否认为一种方法更好通常取决于您要解决的问题。 (我发现 Swift 方法比 TypeScript 方法强大得多。其他人发现 Swift 有限制,因为它不会让你做你“知道”是正确的事情,除非你能向编译器证明它是正确的.)
对于您的示例,仅仅因为两个符号具有相同的拼写(Language.English
和 UNOfficialLanguage.English
)并不意味着它们有任何关联。如果要在它们之间进行转换,则需要在它们之间进行转换。
也就是说,Swift 确实可以方便地转换为字符串和从字符串转换。
enum Language: String {
case english, french, arabic, russian, chinese, spanish, japanese, german, italian
}
enum UNOfficialLanguage: String {
case english, french, arabic, russian, chinese, spanish
}
注意添加 : String
。这使您可以轻松地在枚举和枚举的字符串表示之间进行转换。
let l = UNOfficialLanguage.arabic
let language = Language(rawValue: l.rawValue) // type is Language?
请注意 language
是 Language?
类型,因为此转换可能会失败。由于您碰巧知道 Language 是 UNOfficialLanguage 的超集,因此您可以强制朝那个方向进行转换:
extension Language {
init(_ official: UNOfficialLanguage) {
self.init(rawValue: official.rawValue)!
}
}
let language = Language(l) // type is Language
有关此功能的更多信息,请参阅 Swift 编程语言中的 Raw Values。
查看以下代码:
enum Gender {
case Male, Female, Unknown
}
enum ExplicitGender {
case Male, Female
}
func whatGender(_ g: Gender) {
print("I am \(g)")
}
func makeSureYourGender() -> ExplicitGender {
return ExplicitGender.Male
}
var myGender = makeSureYourGender();
// How to Cast type `ExplicitGender` to `Gender`?
// This fails
// whatGender(myGender)
语法 myGender as ExplicitGender
不正确。
其实Male
,Female
在ExplicitGender
和Gender
中是一样的。
使 2 is 2 different Enum Types 不完全正确。
或者有另一种代码结构或语法来解决这个问题?
另请参阅:
enum Language {
case English, French, Arabic, Russian, Chinese, Spanish, Japanese, German, Italian
}
enum UNOfficialLanguage {
case English, French, Arabic, Russian, Chinese, Spanish
}
在 typescript 中,我将使用:
type UNOfficialLanguage = 'English' | 'French' | 'Arabic' | 'Russian' | 'Chinese' | 'Spanish';
type Language = UNOfficialLanguage | 'Japanese' | 'German' | 'Italian';
您不能(向下转换或向上转换)转换彼此不相关的对象。请查看 casting on swift 以获取有关如何投射的信息。
Gender 和 ExplicitGender 是互不相关的枚举。
一种解决方案是创建一个辅助函数,将 Gender 类型转换为 ExplicitGender 类型,反之亦然。请以下面的代码为例:
func genderFromExplicitGender(gender: ExplicitGender) -> Gender {
switch gender {
case .Male: return .Male
case .Female: return .Female
}
return .Unknown }
这里要注意的是,即使性别和明确性别有男性和女性。无论如何,它们彼此没有关系。上面的代码检查了男性(如 ExplicitGender.Male)和 returns 男性(如 Gender.Male),对女性也是如此。
我会建议您在 swift
中阅读更多关于铸造的内容您的 TypeScript 示例不是枚举。它是字符串文字类型的联合。 Swift 中没有等同于文字类型的东西。 (TypeScript 也有枚举,但它们是不同的东西。)
Swift 和 TypeScript 对于类型的含义有着截然不同的方法。在 TypeScript 中,具有相同结构的两个事物是相同的类型(“结构类型”)。在 Swift 中,两个可以具有相同结构的事物可以是无关的,重要的是类型的名称(“名义类型”)。 TS方式方便,但是有很多类型它不能表达。 Swift方式可以表达更多的东西,但是缺少了一定的便利。
例如,在 TypeScript 中,如果您声明两个具有相同属性的接口,它们是可以互换的:
interface Animal {
legs: number;
}
interface AirTravel {
legs: number;
}
let trip: AirTravel = {legs: 4};
function feedAnimal(a: Animal) {}
feedAnimal(trip) // No problem... legs are legs
Swift中的等效代码会报错:
struct Animal {
var legs: Int
}
struct AirTravel {
var legs: Int
}
let trip = AirTravel(legs: 4)
func feedAnimal(_ a: Animal) {}
feedAnimal(trip)
// error: cannot convert value of type 'AirTravel' to expected argument type 'Animal'
您是否认为一种方法更好通常取决于您要解决的问题。 (我发现 Swift 方法比 TypeScript 方法强大得多。其他人发现 Swift 有限制,因为它不会让你做你“知道”是正确的事情,除非你能向编译器证明它是正确的.)
对于您的示例,仅仅因为两个符号具有相同的拼写(Language.English
和 UNOfficialLanguage.English
)并不意味着它们有任何关联。如果要在它们之间进行转换,则需要在它们之间进行转换。
也就是说,Swift 确实可以方便地转换为字符串和从字符串转换。
enum Language: String {
case english, french, arabic, russian, chinese, spanish, japanese, german, italian
}
enum UNOfficialLanguage: String {
case english, french, arabic, russian, chinese, spanish
}
注意添加 : String
。这使您可以轻松地在枚举和枚举的字符串表示之间进行转换。
let l = UNOfficialLanguage.arabic
let language = Language(rawValue: l.rawValue) // type is Language?
请注意 language
是 Language?
类型,因为此转换可能会失败。由于您碰巧知道 Language 是 UNOfficialLanguage 的超集,因此您可以强制朝那个方向进行转换:
extension Language {
init(_ official: UNOfficialLanguage) {
self.init(rawValue: official.rawValue)!
}
}
let language = Language(l) // type is Language
有关此功能的更多信息,请参阅 Swift 编程语言中的 Raw Values。