我想扩展Array以增加对新协议的一致性 - 但仅适用于其元素本身符合特定协议的数组.
更一般地说,我希望类型参数的类型(无论是协议还是具体类型)仅在类型参数匹配某些约束时才实现协议.
从Swift 2.0开始,这似乎是不可能的.有没有办法让我失踪?
假设我们有Friendly协议:
protocol Friendly {
func sayHi()
}
Run Code Online (Sandbox Code Playgroud)
我们可以扩展现有类型来实现它:
extension String: Friendly {
func sayHi() {
print("Greetings from \(self)!")
}
}
"Sally".sayHi()
Run Code Online (Sandbox Code Playgroud)
我们还可以扩展Array以实现sayHi()其元素全部Friendly:
extension Array where Element: Friendly {
func sayHi() {
for elem in self {
elem.sayHi()
}
}
}
["Sally", "Fred"].sayHi()
Run Code Online (Sandbox Code Playgroud)
此时,类型[Friendly]本身应该实现Friendly,因为它符合协议的要求.但是,此代码无法编译:
extension Array: Friendly where Element: Friendly {
func sayHi() {
for elem in self …Run Code Online (Sandbox Code Playgroud) String百分比转义方法的签名是:
func addingPercentEncoding(withAllowedCharacters: CharacterSet)
-> String?
Run Code Online (Sandbox Code Playgroud)
(这是stringByAddingPercentEncodingWithAllowedCharacters在Swift 2中.)
为什么这个方法返回一个可选的?
文档说该方法返回nil"如果转换不可能",但不清楚在什么情况下转义转换可能会失败:
使用UTF-8转义字符,这是一个完整的Unicode编码.任何有效的Unicode字符都可以使用UTF-8进行编码,因此可以进行转义.
我想也许该方法对允许的字符集和用于转义的字符之间的不良交互应用了某种形式的检查,但事实并非如此:无论允许的字符集是否包含"%",该方法都会成功,如果允许的char集为空,也会成功.
就目前而言,非可选的返回值似乎是强制进行无意义的错误检查.
JSONSerialization.data(withJSONObject:options:)(dataWithJSONObject在Swift 2中也称为)throws.但是,传递无效对象会导致崩溃,而不是可捕获的错误:
do {
// Crash
try JSONSerialization.data(
withJSONObject: NSObject(),
options: [])
}
catch
{
// Never reached
print("Caught error:", error)
}
Run Code Online (Sandbox Code Playgroud)
为什么那个方法被宣布为"抛出"呢?在什么情况下会抛出异常?
不知道导致错误的原因使得很难知道如何处理错误,并且无法编写验证处理错误的测试.
我是框架X的作者,我想分发一些胶水代码,以便可选地与框架Y和Z集成.客户端应该能够使用X作为独立框架,但能够使用集成代码如果他们也使用Y和/或Z.
标题问题是:目前是否有最佳做法,以及权衡什么?详细的子问题如下.
我的具体案例:我是Siesta的作者.只需要一点点代码就可以与SwiftyJSON或Alamofire集成.但是,Siesta不需要这些框架中的任何一个.
我看到两个可接受的选择:
备选方案1乍一看似乎很有希望.这不是确切的可选依赖项吗?但我担心因为:
Cartfile.private来构建X.选项2很简单,但我担心开销.甚至一个noop框架的时钟也超过250k.在最终的应用程序中它仍然是那么糟糕吗?如果我走这条路线,是否存在我应该关注的每个框架开销?
还有其他我不知道的权衡吗?
我正在将CocoaPod升级到Swift 3.它编译并运行得很好,但是pod lib lint由于许多编译器错误而失败,因为linter尝试将所有内容编译为Swift 2.3.
试图SWIFT_VERSION在我的框架的Xcode项目中设置podspec或更改"使用Legacy Swift语言版本"并没有解决问题.
如何让pod linter使用Swift 3?