我有以下代码,我尝试使用Structs
和Protocols
来实现我的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()
答案 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中的约定。)
您的协议扩展可以为方法和计算属性提供默认实现,但不能为存储属性提供默认实现。