面向协议的编程示例不适用于swift 3.0

时间:2017-03-10 04:40:48

标签: ios swift struct swift3 protocols

我有以下代码,我尝试使用StructsProtocols来实现我的Zoo示例。

在这个例子中,我有一个动物园,其中有某种类型的动物具有某种特征。问题的详细信息在repo({{3}})

的自述文件中

我想知道我想要做的是否是正确的做法?下面的代码编译没有任何错误但不起作用。

有人可以帮忙吗?

enum Sex {
    case Male
    case Female
    case Other
}

enum Size:Int {
    case ExtraSmall = 0
    case Small = 1
    case Medium = 2
    case Large = 3
    case ExtraLarge = 4

}

enum Diet {
    case Herbivore
    case Carnivore
}

protocol Animal {
    var sex: Sex { get set }
    var size: Size { get set }
    var diet: Diet { get set }
    var weight: Double { get set }
    var age: Int { get set }
}

protocol Swimmable {
    var swimSpeed: Double { set get }
}

protocol NeedsEclosure {
    func enclosureSize() -> Double
}

protocol Carnivorous {
    func meatSize() -> Double
}

protocol Mammal { }

protocol Fish {
    var adjustedSpeed: Double { set get }
}

protocol Bird { }

protocol Reptile { }

protocol Invertebrate { }

/////Extensions to protocols

extension Animal {
    var weight: Double {
        set {
           self.weight = newValue
        }
        get {
            return weight
        }
    }
    var age: Int{
        set {
           self.age = newValue
        }
        get {
            return age
        }
    }
    var size: Size{
        set {
            self.size = newValue
        }
        get {
            return size
        }
    }
    var diet: Diet{
        set {
            self.diet = newValue
        }
        get {
            return diet
        }
    }
    var sex: Sex{
        set {
            self.sex = newValue
        }
        get {
            return sex
        }
    }
}

extension Swimmable {
    var swimSpeed: Double{
        set {
            self.swimSpeed = newValue
        }
        get {
            return swimSpeed
        }
    }
}

extension NeedsEclosure where Self: Animal {
    func enclosureSize() -> Double {
        return Double(size.rawValue) * weight
    }
}

extension Carnivorous where Self: Animal {
    func meatSize() -> Double {
        return Double(size.rawValue) * weight
    }
}

extension Swimmable where Self: Animal {
    var adjustedSpeed: Double { return (swimSpeed/weight)/Double(age) }
}

/////////////////////////////////
typealias BigCat =  Animal & Mammal & Swimmable & Carnivorous & NeedsEclosure

struct Tiger: BigCat { }

var tiger = Tiger()
tiger.enclosureSize()

1 个答案:

答案 0 :(得分:2)

您定义所有这些计算属性的extension Animal毫无意义。您需要存储的属性。计算的getter(例如weight)对return weight没有任何意义。同样,计算出的setter self.weight = weight也没有用。

您需要存储的属性来存储所有这些值,并且无法在协议扩展中实现存储的属性。考虑Animal的协议:

protocol Animal {
    var sex: Sex { get set }
    var size: Size { get set }
    var diet: Diet { get set }
    var weight: Double { get set }
    var age: Int { get set }
}

您确实需要在某处保留所有这些值,您不能使用协议扩展中定义的计算属性。 (因此,除去定义那些无效计算属性的extension的{​​{1}}。)实际上,您希望在符合此协议的类型中实现这些存储的属性,例如:

Animal

(顺便说一句,我将各种typealias BigCat = Animal & Mammal & Swimmable & Carnivorous & NeedsEnclosure struct Tiger: BigCat { var swimSpeed = 2.0 var size = Size.large var sex = Sex.male var diet = Diet.carnivore var weight = 400.0 var age = 4 } 类型的值更改为使用小写字母,这是Swift 3中的约定。)

您的协议扩展可以为方法和计算属性提供默认实现,但不能为存储属性提供默认实现。