使用协议方法作为curried函数:尝试将函数引用存储到协议蓝图方法会使编译器崩溃

时间:2017-07-18 21:00:06

标签: swift currying

背景

根据Swift Evolution Proposal SE-0002,从Swift 3开始,已经从Swift中删除了curried函数声明。但是,我们可以使用实例方法作为curried函数,并将它们部分应用于定义类型的实例,例如:

struct Foo {
    func bar(_ num: Int) { print("bar \(num)!") }
}

let barFunc = Foo.bar
let fooInstance = Foo()
let partiallyApplied = barFunc(fooInstance)

// invoke remaining (Int) argument
partiallyApplied(42) // bar 42!

与直接在实例上调用实例方法相比:

fooInstance.bar(42)  // bar 42!

查询

现在,协议类型本身无法实例化,但是符合它的某些具体类型可以作为协议类型输入,并且,如果存在默认实现,则完全使用在协议中声明和定义的实例方法。它的扩展(或者,利用它的自定义实现)。例如,方法调用bar(42)动态调度如下:

protocol Foo {
    func bar(_ num: Int)
}

extension Foo {
    func bar(_ num: Int) { print("bar \(num)!") }
}

struct ConcreteFoo : Foo { }

struct AnotherConcreteFoo : Foo { 
    func bar(_ num: Int) { print("barbar \(-num)!") }
}

var foo: Foo = ConcreteFoo()
foo.bar(42) // bar 42!
foo = AnotherConcreteFoo()
foo.bar(42) // barbar -42!

基于上面的背景部分,我们可以争辩说我们同样应该能够使用协议蓝图方法(例如,Foo.bar)作为一个curried函数,就像上面的实例方法一样,以后可以说,我们可以将其部分应用于任何符合协议的类型:

let barFunc = Foo.bar

然而,尝试存储这样的协议方法引用会使编译器崩溃。

  • [Q1]:由于这似乎会使编译器崩溃,这应该是一个错误,对吧?如果是这样,有没有人已经看过它的错误报告(我找不到)?
  • [Q2]:能够在与实例方法相同的currying方法中使用协议蓝图方法是否合理(目的是将其部分应用于符合类型的实例)它会破坏Swift的一些基本的“规则”,这是我所缺少的(协议类型的方法调度)?

(使用Swift 3.1.1 / Linux(x86-64)测试)

0 个答案:

没有答案