我有A类及其子类B,它继承自A。
现在,我在A中有一个类方法,它使用" inout"从某个地方获取实例。并检查它是否为零,如果没有,则用必要的参数填充它。例如:
class A
{
class func fillInstance(inout instance : Self, parameters : [String]) -> Self
{
guard let instance = instance else
{
return Self(parameters : parameters)
}
return instance
}
}
现在,当然没有任何有自我的东西没有效果:)
我需要一种让它有效的方法。在Swift中有可能吗?
这里的一切都是虚构的。我只需要能够实现一个类方法的想法,该方法可以由子进程继承,并允许根据调用该类方法的类实例化实例。我不想检查类型,因为它可以在子层次结构中继承很多次(我的意思是它可以变成A - > B - > C - > D - > E .. ..并且所有人都从另一个继承)。请帮助:)
答案 0 :(得分:1)
你是对的,链赋值不会带有用作参数的类类型。但你可以使用泛型来解决这个问题:
class A
{
class func fillInstance<T:A>(instance : T, parameters : [String]) -> T
{
// do your stuff here
instance.filledContent["A.fillInstance"] = "\(parameters)"
return instance
}
class func fillInstance<T:A>(instance : T?, parameters : [String]) -> T?
{
if instance != nil
{
let existing:T = T.fillInstance(instance!, parameters:parameters)
return existing
}
return nil
}
var filledContent:[String:String] = [:]
}
class B:A
{
func showContent() -> String { return "Showing: \(filledContent)" }
override class func fillInstance<T:A>(instance : T, parameters : [String]) -> T
{
instance.filledContent["B.fillInstance"] = "B Specific Filling"
return A.fillInstance(instance, parameters:parameters)
}
}
let anInstanceOfA = A()
A.fillInstance(anInstanceOfA, parameters: ["A->Param","To A"]).filledContent
// ["A.fillInstance": "["A->Param", "To A"]"]
let anInstanceOfB = B()
A.fillInstance(anInstanceOfB, parameters: ["A->Param","To B"]).showContent()
// "Showing: ["A.fillInstance": "["A->Param", "To B"]"]"
var optionalA:A? = A()
A.fillInstance(optionalA, parameters: ["A->Param","To A?"])?.filledContent
// ["A.fillInstance": "["A->Param", "To A?"]"]
B.fillInstance(optionalA, parameters: ["B->Param","To A?"])?.filledContent
// ["A.fillInstance": "["B->Param", "To A?"]"]
optionalA = nil
A.fillInstance(optionalA, parameters: ["A->Param","To A?(nil)"])?.filledContent
// nil
var optionalB:B? = B()
A.fillInstance(optionalB, parameters: ["A->Param","To B?"])?.showContent()
// "Showing: ["B.fillInstance": "B Specific Filling", "A.fillInstance": "["A->Param", "To B?"]"]"
B.fillInstance(optionalB, parameters: ["B->Param","To B?"])?.showContent()
// "Showing: ["B.fillInstance": "B Specific Filling", "A.fillInstance": "["B->Param", "To B?"]"]"
optionalB = nil
A.fillInstance(optionalB, parameters: ["A->Param","To B?(nil)"])?.showContent()
// nil
B.fillInstance(optionalB, parameters: ["B->Param","To B?(nil)"])?.showContent()
// nil
请注意,无论您使用哪个类函数,编译器始终执行与作为参数给出的实例的类相对应的类函数。 我不确定那是你想要的,然后再说一遍,我无法想象你想要用仅适用于A的逻辑的一部分来填充B的实例的场景(而不是在B覆盖)。
答案 1 :(得分:0)
我不确定这对你有用,但你可以这样做:
class A {
var parameters: [String]!
class func fillInstance(instance: A?, parameters : [String]) -> A? {
if instance == nil {
return self.init(parameters: parameters)
}
instance!.setParameters(parameters)
return instance
}
func setParameters(parameters: [String]) {
self.parameters = parameters
}
required init(parameters: [String]) {
self.parameters = parameters
}
}
您可以将A
的子类的实例发送到fillInstance
:
class B: A {}
let b1 = A.fillInstance(B(), parameters: ["exists"]) as! B
或者您可以从A
的子类发送nil并构造该子类的对象:
let b2 = B.fillInstance(nil, parameters: ["from nil"]) as! B
但是可能有更好的方法来达到你想要的效果。
答案 2 :(得分:0)
这一切对我来说都显得笨拙。除非您的代码打算更改为在传递的变量中交换对象实例,否则根本不需要使用inout。如果这是一个结构,那么可能需要它。
您可以让编译器为您解决此问题:
class A
{
class func fillInstance(instance : A, parameters : [String]) -> A
{
// do your stuff here
return instance
}
class func fillInstance(instance : A?, parameters : [String]) -> A?
{
if instance != nil
{
let existing:A = fillInstance(instance!, parameters:parameters)
return existing
}
return nil
}
}
注意:如果您没有返回实例,这可能会更简单。你不应该认为对象已被修改。或者这只是为了方便制作链式作业?