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を採用するタイプ、 または のサブクラスであるタイプに限定されます。では両方とも不可能で あり、完全なコンパイラ ログで見つけることができます PersonPersonstruct 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 に答える