2

为什么下面的代码不起作用?我需要改变什么才能让它发挥作用?

//: Playground - noun: a place where people can play

import Cocoa

struct Person: CustomDebugStringConvertible, Hashable {
    let name: String
    let age: Int

    // MARK: CustomDebugStringConvertible

    var debugDescription: String {
        return "\(name) is \(age) years old"
    }

    // MARK: Hashable

    var hashValue: Int {
        return name.hashValue ^ age.hashValue
    }
}

func ==(lhs: Person, rhs: Person) -> Bool {
    return lhs.name == rhs.name && lhs.age == rhs.age
}

let ilse = Person(name: "Ilse", age: 33)
let mark = Person(name: "Mark", age: 38)

extension Collection where Iterator.Element: Person {
    var averageAge: Int {
        let sum = self.reduce(0) { $0 + $1.age }
        let count = self.count as! Int
        return sum / count
    }
}

var people = [Person]()
people.append(ilse)
people.append(mark)

let averageAge = people.averageAge

我发现如果我将结构设为 Swift 类,它就可以工作。它与结构是值类型有关吗?我确实在最后一行看到了编译器错误。“'[Person]' 不能转换为 '<>'”

谢谢你。

4

2 回答 2

3
extension Collection where Iterator.Element: Person

仅限Iterator.Element于采用协议的 类型Person 或者是. 两者都是不可能的 ,在完整的编译器日志中你会发现Personstruct Person

错误:类型“Iterator.Element”被限制为非协议类型“Person”

你可能的意思是

extension Collection where Iterator.Element == Person 

这将扩展限制为Person. 或者,定义一个协议

protocol HasAge {
    var age: Int { get }
}

通过Person

struct Person: CustomDebugStringConvertible, Hashable, HasAge { ... }

并为具有年龄的元素集合定义扩展:

extension Collection where Iterator.Element: HasAge { ... }
于 2016-11-09T08:15:55.477 回答
1

将您的收藏的扩展名更改为此

extension Collection where Iterator.Element == Person {
    var averageAge: Int {
        let sum = self.reduce(0) { $0 + $1.age }
        let count = self.count as! Int
        return sum / count
    }
}
于 2016-11-09T08:22:38.927 回答