如果你有这样的协议:
protocol Messaging {
func sendMessage(message: String)
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在类这样的类中满足它:
class Messager: Messaging {
func sendMessage(message: String, count: Int = 1) {}
}
Run Code Online (Sandbox Code Playgroud)
这将是很好的,因为通过添加默认参数来满足协议的结果签名.有没有办法让它与Swift 2一起使用?
这是一个简化的例子.让我们说,为了论证,协议是固定的.解决方案只能更新Messager类.我的目标是能够sendMessage()像这样打电话:
let m: Messaging = Messager()
m.sendMessage("")
Run Code Online (Sandbox Code Playgroud)
我发现完成这个(并满足编译器)的唯一方法是重载,如下所示:
class Messager: Messaging {
func sendMessage(message: String) {
self.sendMessage(message, count: 1)
}
func sendMessage(message: String, count: Int = 1) {}
}
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是我的默认值然后在两个地方指定,我失去了Swift默认参数的主要优点.
最近,我一直在使用Swift开发多个面向协议的应用程序框架,并注意到协议扩展中有一些(看似)奇怪的静态函数行为,特别是从元类型调用扩展函数的情况.
我最初发现这些行为的方式是对一个错误进行故障排除,其中一个对象的类型以一种看似不可能的方式发生了变化.我追查了问题并最终确定这是因为在静态函数中,Self并且self可能存在不同的类型(注意:我已经分别称这些为"Big S Self"和"Little s self").我将用我在游乐场中掀起的一些简单的例子来证明这一点:
class SomeBaseClass: SomeProtocol {}
class SomeChildClass: SomeBaseClass {}
protocol SomeProtocol {}
extension SomeProtocol {
static private func getName() -> String {
return "\(self): \(type(of: self))"
}
static func ambiguousName() -> String {
return getName()
}
static func littleName() -> String {
return self.getName()
}
static func bigName() -> String {
return Self.getName()
}
}
let child: SomeBaseClass.Type = SomeChildClass.self // SomeChildClass.Type
print(child.ambiguousName()) // "SomeChildClass: SomeBaseClass.Type\n"
print(child.littleName()) // "SomeChildClass: SomeBaseClass.Type\n"
print(child.bigName()) …Run Code Online (Sandbox Code Playgroud)