[英]Switch over the generic type in a generic class in Swift
我最近嘗試為 iOS 10 中的Measurement
類型編寫一個擴展,它在通用UnitType
的類型上切換UnitType
。 我想要做的是根據單位類型在UILabel
上指定不同的字符串輸出。 我的目標是簡化用法。
我想出的解決方案是為每種類型的泛型定義一個方法,如下所示:
func localizedDescription(for length: Measurement<UnitLength>) -> String {
// some code
}
func localizedDescription(for speed: Measurement<UnitSpeed>) -> String {
// some code
}
// etc.
我真正想要的是不同的東西,但我無法讓它發揮作用。 也許你可以,或者這是 Swift 到目前為止的限制。 我准備了一個 Swift Playground 來詳細解釋這一點。
這是應該復制這種情況的代碼:
import Foundation
//: Example Classes
class GenericType: NSObject {
// some code
var value: Double {
preconditionFailure("Must be overridden in subclasses.")
}
}
class GenericSubType1: GenericType {
override var value: Double { return 5 }
}
class GenericSubType2: GenericType {
override var value: Double { return 10 }
}
// Note that the class is predefined in a different place, so I can't use the body directly.
class SomeClass<T: GenericType> {
var valueType: T
init(valueType: T) {
self.valueType = valueType
}
}
這是我使用 switch-case 的第一種方法:
//: Switch-Case in Extension
extension SomeClass {
var localizedDescription: String {
switch T.self { // `type(of: T)` doesn't work, `T` does neither
case is GenericSubType1:
return "\(valueType.value) times"
case is GenericSubType2:
return "\(valueType.value) people"
default:
preconditionFailure("Forgot to define a description for generic subclass: \(T.self).")
}
}
}
我在兩條case
行中收到警告,其中指出:
從“T.Type”轉換為不相關的類型“GenericSubType1”總是失敗
我不確定為什么這會給我這個警告,我希望這能按預期工作。 有人可以解釋我嗎? 而且,你會如何最好地解決這種事情?
在寫這個問題時,我嘗試了一些其他的東西,可以想出以下解決方案:
//: Multiple Extensions
extension SomeClass where T: GenericSubType1 {
var localizedDescription: String {
return "\(valueType.value) times"
}
}
extension SomeClass where T: GenericSubType2 {
var localizedDescription: String {
return "\(valueType.value) people"
}
}
現在,當我運行以下代碼時,輸出符合預期:
SomeClass(valueType: GenericSubType1()).localizedDescription // => "5.0 times"
SomeClass(valueType: GenericSubType2()).localizedDescription // => "10.0 people"
這不涉及 switch-case ,所以如果你能做到這一點,我很高興聽到你的回答。 但這可以作為擴展,所以我想分享一下。
如果你想在這種情況下使用開關,你有兩個選擇:
extension SomeClass {
var localizedDescription: String {
switch valueType {
case is GenericSubType1:
return "\(valueType.value) times"
case is GenericSubType2:
return "\(valueType.value) people"
default:
preconditionFailure("Forgot to define a description for generic subclass: \(T.self).")
}
}
}
或者
extension SomeClass {
var localizedDescription: String {
switch T.self {
case is GenericSubType1.Type:
return "\(valueType.value) times"
case is GenericSubType2.Type:
return "\(valueType.value) people"
default:
preconditionFailure("Forgot to define a description for generic subclass: \(T.self).")
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.