所以我在玩协议扩展时遇到了一个“有趣的”问题。
我想编写一个Meters和Kilometers单元类型来测试一些东西。在有一个基类和两个子类覆盖基类的情况下,这样做非常容易,而只是重写一个简单的值。
//Conversion factor between types
enum DISTANCE_UNIT_TYPE : Double {
case METER = 1.0;
case KILOMETER = 0.001;
}
protocol DistanceUnit {
var unitType : DISTANCE_UNIT_TYPE {get}
var value : Double { get set }
var baseValue : Double { get set }
}
struct Kilometers : DistanceUnit {
var unitType = DISTANCE_UNIT_TYPE.KILOMETER
var value : Double
var baseValue : Double
init(_ v : Double) {
value = v
baseValue = v * unitType.rawValue
}
}
struct Meters : DistanceUnit {
var unitType = DISTANCE_UNIT_TYPE.METER
var value : Double
var baseValue : Double
init(_ v : Double) {
value = v
baseValue = v * unitType.rawValue
}
}因此,正如您所看到的,我有很多重复的代码(特别是初始化器)。
我尝试使用协议扩展来设置默认的初始化程序。
extension DistanceUnit {
init(_ v : Double) {
value = v
baseValue = v * unitType.rawValue
}
}但是我得到了一个变量'self‘的错误,它是通过引用传递的,然后才被初始化为。
有什么方法可以让它起作用吗?还是我只需要输入大量重复的代码?也许用unsafe什么的?
发布于 2015-07-08 20:23:22
我假设fqdn是正确的,我们不能像我们想要的那样在其内部协议扩展中使用自定义,但只有时间才能说明这一点。
但仍有一些解决办法:
struct Meters : DistanceUnit {
var unitType = DISTANCE_UNIT_TYPE.METER
var value : Double
var baseValue : Double
init() { // this one is needed as designated initializer for your protocol extension
value = 0
baseValue = 0
}
}
protocol DistanceUnit {
var unitType : DISTANCE_UNIT_TYPE {get}
var value : Double { get set }
var baseValue : Double { get set }
init() // this is new and you will NEED to implement this in your structure or class
}
extension DistanceUnit {
init(_ v : Double) {
self.init()
value = v
baseValue = v * unitType.rawValue
}
// you can now implement a lot more different default inits and they should work fine here :)
// here is a quick example
init(_ s : String) {
self.init(Double(s.characters.count))
}
}希望这能帮到你。几天前,我在构建带有协议扩展(see here)的自定义通用单例生成器时学到了这个技巧。
https://stackoverflow.com/questions/31207908
复制相似问题