1

我正在 Swift 中实现面向协议的方法,如下所示。这个概念看起来很有趣,但我希望你能明白。我的问题是如何为重复的打印任务实现通用功能。谢谢你的进步。

protocol Food {
    var name: String { get }
}

struct Grass: Food {
    var name: String { return "Grass" }
    var calcium: Float!
}

struct Rice: Food {
    var name: String { return "Rice" }
    var calories: Float!
}

struct Insect: Food {
    var name: String { return "Insect" }
    var fiber: Float!
}

protocol Eat {
    associatedtype food: Food
    var name: String { get }
    var itsFood: food { get }
}

struct Cow: Eat {
    typealias food = Grass
    var name: String { return "Cow" }
    var itsFood: food {return food(calcium: 100)}
}

struct People: Eat {
    typealias food = Rice
    var name: String { return "People" }
    var itsFood: food {return food(calories: 1000)}
}

struct Reptile: Eat {
    typealias food = Insect
    var name: String { return "Reptile" }
    var itsFood: food {return food(fiber: 300)}
}

let cow = Cow()
print(cow.name)
print(cow.itsFood.name)
print(cow.itsFood.calcium)

let people = People()
print(people.name)
print(people.itsFood.name)
print(people.itsFood.calories)

let reptile = Reptile()
print(reptile.name)
print(reptile.itsFood.name)
print(reptile.itsFood.fiber)
4

3 回答 3

1

如果我理解正确,您需要一种方法来编写一个函数,该函数可以打印出Eat构象者的名称、食物名称和食物的营养价值。

您当前的Food协议没有获得有关食物营养价值(钙、卡路里、纤维)的足够信息。您应该编辑您的协议:

protocol Food {
    var name: String { get }
    var nutritionalValueName: String { get }
    var nutritionalValue: Float! { get }
}

Food并在conformers中实现 2 个新属性。这是一个例子:

struct Grass: Food {
    var name: String { return "Grass" }
    var calcium: Float!

    var nutritionalValue: Float! { return calcium }
    var nutritionalValueName: String { return "Calcium" }
}

现在,您可以编写一个函数。注意,由于Eat有关联类型,不能直接作为参数类型,需要引入泛型参数T并将其约束为Eat

func printEat<T: Eat>(eat: T) {
    print(eat.name)
    print(eat.itsFood.name)
    print("\(eat.itsFood.nutritionalValueName): \(eat.itsFood.nutritionalValue!)")
}

函数体是不言自明的。

你可以这样称呼它:

printEat(eat: Cow())
printEat(eat: People())
printEat(eat: Reptile())

输出:

Cow
Grass
Calcium: 100.0
People
Rice
Calories: 1000.0
Reptile
Insect
Fiber: 300.0
于 2018-04-25T05:51:50.953 回答
0

我会使用类似下面的东西来在一个地方使用基本功能。您将需要用于通用任务功能的超类,协议还不够。

class Food {
    var name: String? { return nil }
    var calcium: Float?
    var calories: Float?
    var fiber: Float?
}

class Grass: Food {
    override var name: String? { return "Grass" }
    init(_ calcium: Float) {
        super.init()
        self.calcium = calcium
    }
}

class Rice: Food {
    override var name: String? { return "Rice" }
    init(_ calories: Float) {
        super.init()
        self.calories = calories
    }
}

class Insect: Food {
    override var name: String? { return "Insect" }
    init(_ fiber: Float) {
        super.init()
        self.fiber = fiber
    }
}

protocol Eat {
    var name: String? { get }
    var itsFood: Food? { get }
    func printInfo()
}

class Animal: Eat {
    var name: String? { return "Cow" }
    var itsFood: Food? { return Food() }
    func printInfo() {
        print(name ?? "")
        print(itsFood?.name ?? "")
        print(itsFood?.calcium ?? 0)
    }
}

class Cow: Animal {
    override var name: String? { return "Cow" }
    override var itsFood: Grass {return Grass(100) }
}

class People: Animal {
    override var name: String? { return "People" }
    override var itsFood: Food {return Rice(1000)}
}

class Reptile: Animal {
    override var name: String? { return "Reptile" }
    override var itsFood: Food {return Insect(300)}
}

let cow = Cow()
cow.printInfo()
于 2018-04-25T06:48:46.367 回答
0

看看这个:

struct Fruit {

let fruitName : String
let color : String
init(_ name: String,_ color: String) {
    self.fruitName = name
    self.color = color
}
}

    let fruit1 = Fruit("Apple", "Red")
    let fruit2 = Fruit("Grapes", "Green")

    let fruitStack = Stack<Fruit>()
    fruitStack.push(fruit1)
    fruitStack.push(fruit2)

    let fruitFfromStack = fruitStack.pop()
    print("Fruit popped from Stack, Name : \(String(describing: fruitFfromStack?.fruitName)) ,Color : \(String(describing: fruitFfromStack?.color))")
    let fruitFfromStack1 = fruitStack.pop()
    print("Fruit popped from Stack, Name : \(String(describing: fruitFfromStack1?.fruitName)) ,Color : \(String(describing: fruitFfromStack1?.color))")

https://reactcodes.blogspot.com/2019/01/generic-stack-implementation-with.html

于 2019-01-26T11:04:01.197 回答