鉴于此代码:
f
为什么(Foo) -> () -> ()
的类型为(Foo) -> ()
而非Foo.f
?像(Foo) -> …
这样的实例方法可以直接与ng-click="doStepts(1)"
类型的自由函数互换吗?
答案 0 :(得分:2)
为什么
std::sort(objs.begin(), objs.end(), [](const ClassToSort* first, const ClassToSort* second) { return (first->getVal() * 100 + first->getSecondVal()) < (second->getVal() * 100 + second->getSecondVal()); });
的类型为f
而非(Foo) -> () -> ()
?
目前正是如何实现未应用的实例方法引用;他们按照&#34的模型进行了curry函数;给我一个实例,然后我会给你一个部分应用的实例方法&#34; (部分适用于该实例)。
然而,这在某些方面存在问题,首先是因为它通常对于(Foo) -> ()
形式更有用,但更重要的是因为它会导致问题{{1} } 方法。这些最终看起来像(Self, Args...) -> Ret
当前系统,这是有问题的,因为mutating
的变异窗口仅持续呼叫持续时间。
这意味着以下目前正在编译,但实际上是未定义的行为:
(inout Self) -> (Args...) -> Ret
这些是SE-0042背后的主要动机,它会将未应用的实例方法引用从inout
形式更改为形式为struct S {
var i: Int
mutating func increment() {
i += 1
}
}
var s = S(i: 0)
let unappliedIncrement = S.increment
let increment = unappliedIncrement(&s)
increment() // undefined behaviour
(以及{ {1}},(Self) -> (Args...) -> Ret
将为(Self, Args...) -> Ret
- 允许在没有UB的情况下突变实例。
此提案尚未实施,但一旦确定,假设空参数列表变平(因此您不会以尾随inout
参数结束),Self
将确实属于类型为inout Self
。
答案 1 :(得分:0)
这是因为,通过这样说:
let f = Foo.f
您已将f
描述为类方法,Foo.f
。但是在你的Foo声明中,f
是一个实例方法。你因此意外地发现了一个深刻的暗秘,即实例方法是伪装的类方法;你看到了秘密类方法的签名。
如果你说过
let f = Foo().f
你会得到预期的结果。