【问题标题】:Property as a Function Type in a Class属性作为类中的函数类型
【发布时间】:2020-05-07 15:37:20
【问题描述】:

鉴于以下情况:

enum Output {
    case typeA, typeB
}    

class SomeClass {
    var outputFunc: (Int) -> () = methodA // error here

    var output: Output = .typeA {
        didSet {
            if output == .typeA {
                outputFunc = methodA
            }
            else {
                outputFunc = methodB
            }
        }
    }

    func methodA(val: Int) {/* do something */} 
    func methodB(val: Int) {/* do something */} 
}

didSet 中的所有内容都可以正常编译,但在我声明 outputFunc 的地方出现错误:

无法将类型 '(SomeClass) -> (Int) -> ()' 的值转换为指定类型 '(Int) -> ()'

我不确定如何初始化此属性。我尝试将其更改为self.methodA,但显然self 还不存在。如果我将outputFunc 的类型更改为(SomeClass) -> (Int) -> (),则属性会编译,但didSet 会给我相反的错误。

【问题讨论】:

  • “我不知道如何初始化这个属性。我试过把它改成self.methodA,但显然self还不存在。”。确切地!如果你已经明白self此时不存在,那么你应该明白为什么你不能做var outputFunc: (Int) -> () = methodAmethodAself.methodA 是一回事。
  • 正如@Sweeper 所说,您还没有self 可用,但如果您愿意在首次使用时对其进行初始化,您可以将其更改为lazy 属性。

标签: swift function types properties


【解决方案1】:

该错误消息可能更具描述性,因为真正的错误确实是您在准备好之前尝试访问self,因为outputFunc 是一个实例属性,而methodA 是一个实例方法。

要解决此问题,您只需将outputFunc lazy 设为即可。

lazy var outputFunc: (Int) -> () = methodA

【讨论】:

    【解决方案2】:

    既然你说

    但显然 self 还不存在

    您似乎明白在初始化程序中初始化所有属性之前,您无法访问self。好吧,methodAself.methodA 实际上是一回事。前者只是后者的缩写,因为self在没有歧义的情况下通常不需要。

    一种解决方案是在初始化器中初始化它,先将outputFunc 初始化为其他东西:

    init() {
        outputFunc = {_ in}
        outputFunc = methodA
    }
    

    但我个人认为,当类/结构未正确初始化时,允许您将方法分配给属性没有任何危险。这个限制可以防止这样的事情发生(人为的例子):

    class Foo {
        var foo = f() // foo's value should be the return value of f...
        func f() -> Int {
            print(foo) // but to execute f, we need the value of foo...
            return foo + 1 // so what is the value of foo?
        }
    }
    

    但是由于您实际上并没有调用methodA,所以我看不出这个分配如何导致问题。我的猜测是他们只是禁止所有使用self,不允许任何例外,因为这样更容易实现。

    【讨论】:

      猜你喜欢
      • 2021-02-04
      • 2019-03-31
      • 2021-04-09
      • 2012-09-14
      • 2022-11-17
      • 2016-05-13
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多