2016-08-02 46 views
2

假设您有一个协议ToString,该协议实现了Int,并且该函数使用一个数组ToString s。Swift:将实际类型数组转换为协议类型数组

试图将Int的数组传递给此函数会导致错误Cannot convert value of type '[Int]' to expected argument type '[ToString]'

但是,在将数组传递给函数之前,使用map作用。这是假设的方式来做类型转换或有没有办法不会导致迭代数组?或者编译器对此进行了优化?

完整的示例:

protocol ToString { 
    func toString() -> String 
} 

extension Int: ToString { 
    func toString() -> String { 
    return "\(self)" 
    } 
} 

func log(values: [ToString]) { 
    values.forEach { print($0.toString()) } 
} 

let values: [Int] = [1, 2, 3] 

// Error: Cannot convert value of type '[Int]' to expected argument type '[ToString]' 
log(values) 

// No error 
log(values.map { $0 }) 
+3

错误的原因是“无法将类型的值[Int]'转换为期望的参数类型'[ToString]''”,这里解释为:[在Swift中使用协议时的类型转换](http://stackoverflow.com/questions/38387256 /使用protocol-in-swift时的类型转换):将[Int]转换为[ToString]需要转换每个元素。 - 所以这部分是重复的。但是,既然你要求其他解决方案(下面给出一个解决方案),我决定放弃它。 –

回答

3

This Q&A说明问题。我会建议避免新阵列的创建的修复:使你的log功能通用,并添加一个类型约束其类型参数,要求其遵守ToString协议:

func log<T:ToString>(values: [T]) { 
    values.forEach { print($0.toString()) } 
} 

现在斯威夫特让你打电话给你函数与任何类型的数组,只要数组元素符合ToString协议。

+0

感谢您提供问答环节和答案。它很好地解决了我的问题,尽管我遇到的实际问题是我想将一个数组从一个子协议转换为一个超级协议的数组,并且实际类型可能并不相同。但我想我会将这个问题添加到链接的问答中。 – lassej

相关问题