Swift隐式传递self作为引用类型的inout参数

Swift隐式传递self作为引用类型的inout参数,swift,Swift,是否可以隐式地将self作为inout参数传递,以就地修改参考变量 下面是一个可以将抽象基类转换为其具体子类的方法。我的问题是,我必须始终使用第一个参数,obj:inout AbstractBaseClass,还是可以隐式传递self。我意识到这也可以表示为静态方法 func convertTo(_ obj: inout AbstractBaseClass, _ type: ConcreteClassTypes) { switch type { case

是否可以隐式地将
self
作为
inout
参数传递,以就地修改参考变量

下面是一个可以将抽象基类转换为其具体子类的方法。我的问题是,我必须始终使用第一个参数,
obj:inout AbstractBaseClass
,还是可以隐式传递self。我意识到这也可以表示为静态方法

    func convertTo(_ obj: inout AbstractBaseClass, _ type: ConcreteClassTypes) {
        switch type {
        case .concreteClass1: obj = ConreteClass1()
        case .concreteClass2: obj = ConcreteClass2()
        }
    }
以下是完整的代码:

class AbstractClass {

    enum ConcreteType {
        case concreteClass1
        case concreteClass2
    }

    var id: Int = 0

    fileprivate init() { }

    func convert(_ obj: inout AbstractClass, to type: ConcreteType) {

        let oldId = obj.id

        switch type {
        case .concreteClass1: obj = ConcreteClass1()
        case .concreteClass2: obj = ConcreteClass2()
        }

        obj.id = oldId
    }

    class ConcreteClass1: AbstractClass {

        override init() { super.init() }
    }

    class ConcreteClass2: AbstractClass {

        override init() { super.init() }

    }

}

var obj: AbstractClass = AbstractClass.ConcreteClass1()
obj.convert(&obj, to: .concreteClass2) //is there any way to eliminate this first argument?
…是否就地修改引用变量?下面是一个可以将抽象基类转换为其具体子类的方法

您没有“修改”或“转换”任何内容。您正在用一个对象替换另一个对象。因此,这里没有可以传递的
self
;你所做的就是摧毁一个
自我
,并提供另一个来代替它

也就是说,
inout
变量的用途有点不清楚。为什么不指定新对象来代替旧对象呢

func giveMeA( _ type: AbstractClass.ConcreteType) -> AbstractClass {
    switch type {
    case .concreteClass1: return AbstractClass.ConcreteClass1()
    case .concreteClass2: return AbstractClass.ConcreteClass2()
    }
}

var obj: AbstractClass = AbstractClass.ConcreteClass1()
obj = giveMeA(.concreteClass2)
效果与您所做的相同。如果您认为不是这样,那么您只是在拿
inout
参数在做什么开玩笑

…是否就地修改引用变量?下面是一个可以将抽象基类转换为其具体子类的方法

您没有“修改”或“转换”任何内容。您正在用一个对象替换另一个对象。因此,这里没有可以传递的
self
;你所做的就是摧毁一个
自我
,并提供另一个来代替它

也就是说,
inout
变量的用途有点不清楚。为什么不指定新对象来代替旧对象呢

func giveMeA( _ type: AbstractClass.ConcreteType) -> AbstractClass {
    switch type {
    case .concreteClass1: return AbstractClass.ConcreteClass1()
    case .concreteClass2: return AbstractClass.ConcreteClass2()
    }
}

var obj: AbstractClass = AbstractClass.ConcreteClass1()
obj = giveMeA(.concreteClass2)

效果与您所做的相同。如果您认为不是这样,那么您只是在开玩笑说
inout
参数在做什么。

像matt一样,我不相信
inout
是这种情况下工作的正确工具

尽管如此,如果您坚持这样做,实现您想要的一种方法是(ab)使用协议扩展。它们允许定义
mutating
方法,将隐式
self
参数作为
inout
传递(允许采用值类型的变异)

所以你可以说:


但是这有点像黑客,我会小心使用它。

像马特一样,我不相信在这种情况下,
inout
是正确的工作工具

尽管如此,如果您坚持这样做,实现您想要的一种方法是(ab)使用协议扩展。它们允许定义
mutating
方法,将隐式
self
参数作为
inout
传递(允许采用值类型的变异)

所以你可以说:


但这有点像黑客,我会小心使用它。

我将提出一种完全不同的方式来看待您试图做的事情

没有抽象的超类。没有多个子类。拥有一个具有多个功能变体的类。函数变体由类实例拥有的helper对象(结构)表示

因此,要更改功能,只需将助手设置为不同类型的助手。基本上,你给你的对象一个人格移植


我有一个这样的应用程序。我有四个视图控制器,它们以稍微不同的方式呈现稍微不同的信息。但事实上,它们是一个视图控制器和一个枚举,有四种情况说明了这些差异。因此,视图控制器可以在任何时候显示为这四种类型中的任何一种。

我将提出一种完全不同的方式来看待您尝试执行的操作

没有抽象的超类。没有多个子类。拥有一个具有多个功能变体的类。函数变体由类实例拥有的helper对象(结构)表示

因此,要更改功能,只需将助手设置为不同类型的助手。基本上,你给你的对象一个人格移植


我有一个这样的应用程序。我有四个视图控制器,它们以稍微不同的方式呈现稍微不同的信息。但事实上,它们是一个视图控制器和一个枚举,有四种情况说明了这些差异。因此,视图控制器在任何时候都可以表现为四种类型中的任何一种。

“它可以将抽象基类转换为其具体子类之一”–为什么要从抽象基类的实例开始?首先,您通常不想实例化抽象类。“它可以将抽象基类转换为它的一个具体子类”-为什么要从抽象基类的实例开始?您通常不想首先实例化一个抽象类。谢谢。其目的还在于将原始对象的参数复制到新对象,同时替换类型。将更新我的代码“目的也是将原始对象的参数复制到新对象上”,但我不认为这与我所说的有丝毫区别。你可以把原稿传进来,也可以把信息发送给原稿,但是输出的是另一个对象,你用它来代替原稿。其目的还在于将原始对象的参数复制到新对象,同时替换类型。将更新我的代码“目的也是将原始对象的参数复制到新对象上”,但我不认为这与我所说的有丝毫区别。你可以把原稿传进来,也可以把信息传给原稿,但是出来的是另一个对象,你用它来代替原稿。这实际上是我一直在做的——我定义了不同的per