Ios 调用Swift协议初始值设定项
Swift 5,在XCode 11.2.1上。我一直在用Java编程,目前对Swift的熟练程度还不算高,所以我对Java习语的一些理解是有色彩的 假设我们提供了一个协议,或者可能是一个伪抽象类,它可以在单独的模块中实现。然后,程序员将对他们的类的引用传递回第一个模块中的代码,该模块实例化了他们的类。现在,在Java中,这很困难,因为您无法保证子类将定义什么样的初始值设定项/静态方法。但是,在Swift中,您可以。这很整洁。除了,我还没有找到使用它们的方法。我所期望的是,你可以有这样的代码Ios 调用Swift协议初始值设定项,ios,swift,types,static,swift-protocols,Ios,Swift,Types,Static,Swift Protocols,Swift 5,在XCode 11.2.1上。我一直在用Java编程,目前对Swift的熟练程度还不算高,所以我对Java习语的一些理解是有色彩的 假设我们提供了一个协议,或者可能是一个伪抽象类,它可以在单独的模块中实现。然后,程序员将对他们的类的引用传递回第一个模块中的代码,该模块实例化了他们的类。现在,在Java中,这很困难,因为您无法保证子类将定义什么样的初始值设定项/静态方法。但是,在Swift中,您可以。这很整洁。除了,我还没有找到使用它们的方法。我所期望的是,你可以有这样的代码 pr
protocol FooP {
init(s: String)
}
func instantiate(clazz: FooP.Type) -> FooP {
return clazz.init(s: "qwerty")
}
…哦,哦,rrrrr,这确实有效,正如我所希望的那样。我想在我的测试中,我没能找到CLASS/.Type/.self的正确组合来提示我成功的可能性
由于我没有找到关于这种可能性的任何其他信息,尽管搜索了30-60分钟,我还是会回答我自己的问题。事实证明,您可以使用协议给出的静态方法,即使所涉及的类(不是其实例化)被强制转换为它们的协议。您甚至可以使用泛型使示例
实例化
方法更方便地具有给定类型的返回类型,尽管这会导致如下所示的不同问题。下面是一组代码,演示了您可以做和不能做的事情:
public protocol ProtocolTest {
init(s: String)
static func factory(s: String) -> Self
}
public class Foo : ProtocolTest, CustomStringConvertible {
public let s: String
public required init(s: String) {
self.s = s
}
public class func factory(s: String) -> Self {
return Self(s: s)
}
public var description: String { return "{\(Self.self)|s:\"\(s)\"}" }
}
public class Bar : Foo {
}
public func instantiateGeneric<T : ProtocolTest>(clazz: T.Type) -> T {
return clazz.init(s: "qwertyGeneric")
}
public func instantiateNongeneric(clazz: ProtocolTest.Type) -> ProtocolTest {
return clazz.init(s: "qwertyNongeneric")
}
public func run() {
let ptts: [ProtocolTest.Type] = [Foo.self, Bar.self]
// Success
let aInit : Bar = Bar.init(s: "qwertyInit")
// Success
let aGeneric : Bar = instantiateGeneric(clazz: Bar.self)
// Compile error: Cannot convert value of type 'ProtocolTest' to specified type 'Bar'
let aNongeneric : Bar = instantiateNongeneric(clazz: Bar.self)
for ptt in ptts {
// Success
let bInit : ProtocolTest = ptt.init(s: "qwertyInit")
// Compile error: Protocol type 'ProtocolTest' cannot conform to 'ProtocolTest' because only concrete types can conform to protocols
let bGeneric1 : ProtocolTest = instantiateGeneric(clazz: ptt)
// Compile error: Cannot invoke 'instantiateGeneric' with an argument list of type '(clazz: ProtocolTest.Type)'
let bGeneric2 = instantiateGeneric(clazz: ptt)
// Success
let bNongeneric : ProtocolTest = instantiateNongeneric(clazz: ptt)
// This works too, btw:
let bFactory : ProtocolTest = ptt.factory(s: "qwertyFactory")
}
}
公共协议协议测试{
init(s:String)
静态函数工厂(s:String)->Self
}
公共类Foo:ProtocolTest,CustomStringConvertible{
公共let s:String
公共必需的init(s:String){
self.s=s
}
公共类函数工厂(s:String)->Self{
返回自我(s:s)
}
公共变量描述:字符串{return“{\(Self.Self){s:\”\(s)\“}”
}
公共类酒吧:富{
}
公共函数实例化eneric(clazz:T.Type)->T{
返回clazz.init(s:“qwertyGeneric”)
}
public func instantiateNongeric(clazz:ProtocolTest.Type)->ProtocolTest{
返回clazz.init(s:“qwertyNongeneric”)
}
公共职能运行(){
让ptts:[ProtocolTest.Type]=[Foo.self,Bar.self]
//成功
让aInit:Bar=Bar.init(s:qwertyInit)
//成功
让aGeneric:Bar=instantialegeneric(clazz:Bar.self)
//编译错误:无法将“ProtocolTest”类型的值转换为指定的“Bar”类型
让aNongeneric:Bar=实例化aNongeneric(clazz:Bar.self)
用于ptt中的ptt{
//成功
让bInit:ProtocolTest=ptt.init(s:“qwertyInit”)
//编译错误:协议类型“ProtocolTest”无法符合“ProtocolTest”,因为只有具体类型才能符合协议
让bGeneric1:ProtocolTest=instantiateGeneric(clazz:ptt)
//编译错误:无法使用类型为“(clazz:ProtocolTest.type)”的参数列表调用“InstanceGeneric”
设bGeneric2=instantialegeneric(clazz:ptt)
//成功
让bNongeneric:ProtocolTest=实例化nongeneneric(clazz:ptt)
//这也行,顺便说一下:
让bFactory:ProtocolTest=ptt.factory(s:“qwertyFactory”)
}
}
我不确定循环中的
instantialegeneric
到底是怎么回事。这似乎是一个合理的代码行。如果你有什么解释,请告诉我。也许关于
,协议测试
在技术上不符合协议测试
,或者它必须是一个严格的子类?不确定。这将是很好的,能够使用相同的方法为两种用途,但我很高兴我能做的,已经。这个发现可能足以让我真正喜欢上斯威夫特,哈哈。有趣的事实:在一个类中,static func
相当于final class func
。另外有趣的事实:似乎当你试图对你的类型产生兴趣的时候,斯威夫特马上就开始攻击你了。例如,显然,如果不指定类型参数,就不能使用泛型类。而且没有任何通配符。