我想在Swift中懒惰/内联实现一个协议。因此,在实现时,我将可以访问协议范围之外的变量,
与在Java中实现接口而不声明类相同:
class MyClass:UIView {
var someComponent:SomeInnerComponent = SomeInnerComponent();
var count:Int = 0;
var a = :SomeProtocol { //<----- IS THIS POSSIBLE, IF YES HOW ?
func a0() {MyClass.count--}
func a1() {MyClass.count++}
}
someComponenet.delegate = a;
}
protocol SomeProtocol {
func a0()
func a1()
}
编辑----
谢谢,我看着这个解决方案,但我没有看到如何访问父类的变量。所有的示例都显示了一个匿名类,但是没有一个示例在访问父变量。
您正在寻找的是一个内部类(不一定是匿名类),该类在一个范围内声明,该范围允许它访问实例的count
变量MyClass
,并采用在另一个范围内定义的协议。目前,Swift包含了其中的一些内容,但看起来似乎您无法以所需的任何简洁方式将它们放在一起。
您可能会考虑声明一个内部类:
class MyView: UIView {
let someComponent = SomeInnerComponent() // type SomeInnerComponent is inferred
var count = 0 // type Int is inferred
class Helper: SomeProtocol {
func a0() { count-- } // ERROR
// ...
}
init() {
someComponent.delegate = Helper()
}
}
但是,这是行不通的,因为count
是含蓄self.count
,这里self
是一个Helper
实例,而不是MyView
“拥有”的实例Helper
的实例。而且,没有一种方法可以MyView
从的方法中引用该实例(或其属性)Helper
,因为您可以在MyView.Helper()
没有现有MyView
实例的情况下构造一个。Swift中的内部类(或通常的嵌套类型)仅在词汇范围内嵌套,而在存在所有权上不嵌套。(或者换一种说法,因为您引用了Java:Swift中的所有内部类都像Java中的静态内部类。没有非静态内部类。)但是,如果您要使用此功能,可能值得一讲苹果要。
您也可以尝试在Helper
内部声明MyView.init()
-在Swift中,您可以在任何地方嵌套类型定义,包括内部函数或其他类型的方法。在此处定义,它可以引用MyView
的属性。但是,现在for的类型信息Helper
仅在中可见MyView.init()
,因此当您将其分配给someComponent.delegate
(类型为SomeProtocol
)时,就无法使用它……这甚至使编译器崩溃。(这是另一个要报告的错误,但是很难说该错误是“在有效使用情况下编译器崩溃”还是“代码不好,但是编译器崩溃而不是产生错误”。)
我能想到的最接近的解决方案如下所示:
class SomeInnerComponent {
var delegate: SomeProtocol?
}
protocol SomeProtocol {
func a0()
func a1()
}
class MyClass {
var someComponent = SomeInnerComponent()
var count = 0
struct Helper: SomeProtocol {
var dec: () -> ()
var inc: () -> ()
func a0() { dec() }
func a1() { inc() }
}
init() {
someComponent.delegate = Helper(
dec: { self.count -= 1 }, // see note below
inc: { self.count += 1 }
)
}
}
这个怎么运作:
Helper
是内部结构(可以是类,但是结构更简单)a0
和a1
方法,满足SomeProtocol
a0
和a1
通过对封闭呼叫dec
和inc
,其在本的存储特性(又名实例变量)Helper
结构Helper
实例(使用默认成员明智的初始化,Helper(dec: (Void -> Void), inc: (Void -> Void))
)Helper
,因此这些闭包可以捕获您正在调用初始化程序的变量,包括self
指向MyClass
创建的实例的隐式变量Helper
。您需要a0
/a1
和dec
/,inc
因为您需要闭包(后者)而不是方法来捕获封闭状态。即使闭包和函数/方法在许多方面可以互换,您也无法通过将闭包分配给方法/函数名称来创建方法/函数实现。(如果SomeProtocol
需要闭包属性而不是方法,那将是另外一回事了,但我认为SomeProtocol
这不是您所能控制的。)
无论如何,这可能是很多样板和您可能不需要的抽象层,因此可能值得研究构建代码的其他方法。
注意:我的示例{ self.count -= 1 }
在您可能期望的地方使用了闭包{ self.count-- }
。后者不起作用,因为那是一个带有值的表达式,因此Swift会将其解释为闭包返回值的简写。然后,它会抱怨您() -> Int
为期望() -> ()
(aka Void -> Void
)闭包的属性分配了闭包。使用-= 1
代替可解决此问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句