我最近尝试在iOS 10中编写Measurement
类型的扩展程序,切换案例超过通用 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 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'始终失败
我不确定为什么这会给我这个警告,我希望这能按预期工作。有人可以解释一下吗?而且,你最好如何解决这类问题?
答案 0 :(得分:1)
在撰写问题时,我尝试了其他一些方法,并提出以下解决方案:
//: 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"
这个不涉及开关案例,所以如果你能做到这一点,我会很高兴听到你的回答。但这可以作为扩展,所以我想分享。
答案 1 :(得分:0)
如果你想在这种情况下使用开关,你有两个选择:
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).")
}
}
}