2016-11-09 36 views
2

为什么以下代码不起作用?我需要改变什么才能使它工作?Swift 3 - 集合中的结构

//: 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 

我想通了,如果我做了一个结构斯威夫特类它的工作原理。它是否与作为值类型的结构有关?我在最后一行看到编译器错误。 ''[Person]'不可转换为'<''“

谢谢。

回答

3
extension Collection where Iterator.Element: Person 

限制Iterator.Element到采用协议Person 或是子类的Person类型。无论是不可能的 struct Person,并在完整的编译器登录,你会发现

error: type 'Iterator.Element' constrained to non-protocol type 'Person'

什么你大概的意思是

extension Collection where Iterator.Element == Person 

这限制了扩展的Person集合。 或者,通过Person

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

定义一个协议

protocol HasAge { 
    var age: Int { get } 
} 

采用的是和定义的扩展对于具有时代元素的集合:

extension Collection where Iterator.Element: HasAge { ... } 
+0

谢谢你的解释。我甚至不知道Iterator.Element == Person是可能的。 –

+0

@ user3654258:这种“相同类型的需求”对于'Collection'(它本身就是一种协议)是可能的,但目前不适用于'Array'(这是一个通用结构)。 –

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 
    } 
}