当前位置: 首页 > 知识库问答 >
问题:

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

欧阳高昂
2023-03-14

我试图构造一个包含可选闭包的表。当我尝试实例化表的实例时,传递闭包的成员函数,我会得到一个编译错误。

从错误 msg 中可以看出,成员函数无法转换为可选的成员函数。我不明白为什么不;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
    }
}

无法转换类型为“”的值-

共有1个答案

左丘成天
2023-03-14

您刚刚发现成员函数(又称实例方法)是用Swift编写的。请参见实例方法是Swift中的“Curried”函数

Foo。doSomething(_:)不仅仅是一个自由函数(也称为全局函数)。它是一个实例方法,可以访问实例self。但是如果直接将该方法作为闭包,它不知道<code>self</code>的值是多少。

有几个选项:

>

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

    或者,您可以通过将其保持在原来的位置并使用<code>static</code>修饰符将其转换为静态函数。与全局函数相比,它还有一个额外的好处,即它通过将代码移动到适当的名称空间来“组织”代码。

    如果< code>doSomething(_:)的实现确实需要一个实例来操作,则可以访问该实例的unapplied方法。这里有一个例子。我已经为演示添加了显式类型注释,但是您通常应该省略它们。

    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)
    

  •  类似资料:
    • 问题内容: 我试图了解Go在创建带有参数的匿名函数与将该函数用作闭包之间的区别。这是区别的一个例子。 带参数: 作为关闭: 我的问题是,第一种形式何时比第二种更好?您是否会为此类事情使用参数?我唯一看到第一种形式有用的是从另一个函数返回a时。 问题答案: 使用闭包与使用函数参数之间的区别在于共享同一变量与获取值的副本有关。请考虑下面的两个示例。 在 Closure中, 所有函数调用都将使用中存储的

    • 我编写了一个代码来传递函数指针列表(按其名称)作为参数。但我有错误。你能解释为什么我在做地图时有错误吗? 错误: 34:18:错误:无法将'void(Bar::)(int, int)'转换为'std::map, void(*)(int, int) 35:18:错误:无法将“无效(foo::)(整数,整数)”转换为“标准::映射,无效(*)(整数,整型) 41:70:错误:没有用于调用“std::v

    • 我正在尝试设置一个“事件接收器”类,将GLFW回调封装到用户可以从中继承的类中,但在将基类成员函数传递到GLFW“set callback”函数中时遇到问题。 这本质上提供了一个带有纯虚拟函数的基类,供用户继承和重写,以便在事件发生时提供自己的逻辑。用户定义的子类将被传递到更大的“应用程序框架”类中,该类将进行必要的调用以设置GLFW回调函数。 当然,您不能将成员函数作为函数参数传递,因为您必须提

    • 我有一个函数,它有两个参数,最后一个参数是回调闭包: 我想让第二个回调闭包参数可选。我试图将上面的函数重新定义为: 我收到编译器错误: nil默认参数值不能转换为类型'

    • 以这种方式传递参数有问题,我得到以下错误:“std::thread::thread”:没有重载函数接受4个参数。我怎么能这么做?

    • 我在代码中使用STD::Thread时遇到问题: 我得到以下错误: 我的问题看起来像是重复的,但只有一点不同,在另一个问题的答案中,std::Thread是在类声明或实现之外使用的,它是在main()中使用的,在这种情况下,指定范围对我来说是有意义的,但当std::Thread在类内部调用时就没有意义了。这是我看到的唯一区别,也是为什么我做了这个线程,很抱歉可能会重复。