我有一个带有方法的协议(protocol)。我一直以为方法可以用同名的闭包代替,但是好像不行:
protocol Foo {
func bar() // Type: Void -> Void
}
class X: Foo {
func bar() { }
}
class Y: Foo { // Compiler: doesn't conform to protocol Foo
let bar: Void->Void = {}
}
有没有办法让它工作?我想覆盖测试 stub 实现的方法行为。目前,我必须这样做,我想缩短它:
class Z: Foo {
var barClosure: Void -> Void = {}
func bar() {
barClosure()
}
}
let baz = Z()
baz.barClosure = { /* ... */ }
baz.bar() // Calls the closure replacement
最佳答案
感谢@Dániel Nagy,我能够弄清楚我有哪些选择。该协议(protocol)应要求关闭。这样,客户端代码就不会改变,因为闭包调用与方法调用相同。
- 使属性可变,以便实现可以决定是否要锁定该值
- 只需要一个 setter/getter (出于同样的原因)
- 在生产代码中将属性初始化为不可变 (
let
) - 在测试代码中将属性初始化为可变 (
var
) 以在测试用例中提供替代实现,就像模拟观察者所做的那样
这是一个修改后的示例,它通过返回字符串在 Playground 中运行良好:
protocol Foo {
var bar: () -> String { get }
}
class X: Foo {
// cannot be overwritten
let bar: () -> String = { return "default x" }
}
class Y: Foo {
private let _bar: () -> String = { return "default y" }
// Can be overwritten but doesn't have any effect
var bar: () -> String {
get {
return _bar
}
set {
}
}
}
class Z: Foo {
// Can be overwidden
var bar: () -> String = {
return "default z"
}
}
let bax = X()
bax.bar() // => "default x"
// bax.bar = { /* ... */ } // Forbidden
let bay = Y()
bay.bar() // => "default y"
bay.bar = { return "YY" }
bay.bar() // => "default y"
let baz = Z()
baz.bar() // => "default z"
baz.bar = { return "ZZ" }
baz.bar() // => "ZZ"
关于swift - 使用闭包属性满足 Swift 协议(protocol)方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28496120/