gpt4 book ai didi

Swift 将成员函数传递给采用可选闭包的函数

转载 作者:行者123 更新时间:2023-11-28 07:22:10 25 4
gpt4 key购买 nike

我正在尝试构建一个表,其中包含一个可选的闭包。当我尝试实例化表的一个实例时,为闭包传递一个成员函数时,出现编译错误。

从错误消息看来,成员函数无法转换为可选成员函数。我不明白为什么不; Int 或其他类型可以很容易地转换为可选值。

struct Foo {

typealias Routine = (_ x: Int) -> Int
let int: Int
let aRoutine: Routine?

init(_ int: Int, _ routine: Routine? = nil) {
self.int = int
self.aRoutine = routine
}
}

class Bar {

let foo = Foo(5, doSomething) // Compile error here

func doSomething(_ x: Int) -> Int {
return x
}
}

Cannot convert value of type '(Bar) -> (Int) -> Int' to expected argument type 'Foo.Routine?' (aka 'Optional<(Int) -> Int>')

最佳答案

您刚刚发现成员函数(又名实例方法)在 Swift 中是柯里化(Currying)的。参见 Instance Methods are “Curried” Functions in Swift

Foo.doSomething(_:) 不仅仅是一个免费函数(又名全局函数)。它是一个可以访问实例 self 的实例方法。但是如果直接把方法当作闭包,它并不知道self的值是什么。

有几个选项:

  1. 如果您的doSomething(_:) 实现不需要访问self,那么您可以将它移出Foo 的声明,并将其声明为全局函数。

    或者,您可以将其保留在原处并使用 static 修饰符将其转换为静态函数。这比全局函数有一个额外的好处,因为它通过将代码移动到适当的命名空间来“组织”您的代码。

  2. 如果您的 doSomething(_:) 实现 确实 需要一个实例来操作,那么您可以访问该实例的未应用方法。这是一个例子。我已经为演示添加了显式类型注释,但您通常应该忽略它们。

    let object: Bar = Bar() // an object of type Bar

    let boundDoSomethingMethod: (Int) -> Int = object.doSomething // a bound method which operates on `object`

    // alternatively:
    let unboundDoSomethingMethod: (Bar) -> (Int) -> Int = Bar.doSomething
    let boundDoSomethingMethod: (Int) -> Int = unboundDoSomethingMethod(object)

关于Swift 将成员函数传递给采用可选闭包的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57749153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com