我想懒惰/内联在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()
}
编辑----
谢谢我看看这个解决方案,我没有看到如何访问父类的变量。 所有示例都显示了一个Anonymous类,但没有一个示例正在访问父变量。
答案 0 :(得分:3)
你正在寻找的是一个内部类(不一定是匿名的),在一个范围内声明,允许它访问count
实例的MyClass
变量,并且采用协议在不同的范围内定义。现在,斯威夫特有一些这样的作品,但看起来你看起来并不像他们想要的那样简洁。
您可能会考虑声明一个内部类:
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中的静态内部类。没有非静态内部类。)如果这是你想要的功能,{{3} }。
您也可以尝试在Helper
内声明MyView.init()
- 在Swift中,您可以在任何地方嵌套类型定义,包括内部函数或其他类型的方法。在那里定义,它可以引用MyView
的属性。但是,现在Helper
的类型信息仅在MyView.init()
内可见,因此当您将其分配给someComponent.delegate
(其类型仅为SomeProtocol
)时,您不能利用它...这甚至会使编译器崩溃。 (那是另一个it's probably worth telling Apple you want it,但是很难说这个错误是“编译器在有效使用时崩溃”还是“代码坏了,但编译器崩溃而不是产生错误”。)
我能想出的最接近的解决方案看起来像这样:
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
,因为您需要用于捕获封闭状态的闭包(后者),而不是方法。即使闭包和funcs /方法在很多方面可以互换,也不能通过为方法/ func名称分配闭包来创建方法/ func实现。 (如果SomeProtocol
需要闭包属性而不是方法,那将是一个不同的故事,但我假设SomeProtocol
不是你控制的东西。)
无论如何,这可能是一些你可能并不真正需要的样板和抽象层,因此可能值得研究构建代码的其他方法。
注意:我的示例使用了您可能期望{ self.count -= 1 }
的闭包{ self.count-- }
。后者不起作用,因为这是一个带有值的表达式,因此Swift会将其解释为闭包的返回值的简写。然后它会抱怨你为一个期望() -> Int
(又名() -> ()
)关闭的属性分配了Void -> Void
个闭包。使用-= 1
可以解决此问题。