为什么泛型不使用自身的具体版本?

时间:2017-01-29 20:46:27

标签: swift generics

TL; DR

  • 为什么我们不能在其自己的通用实现中使用泛型类型的具体版本?由于它是一种具体的类型,我认为没有问题"递归打字"。这是一个设计决定吗?还是目前的限制?

背景

当玩弄仿制药时,我偶然发现以下(对我来说,以前未知)的好奇心:

struct Foo<T> { let foo: T }

struct Bar<U> {
    let bar: U

    func foobar() -> Foo<Bar> {
                   /* ^^^ Bar<U> inferred */
        // no matter of the actual implementation ...
        return Foo(foo: self)
    }

    // even without inference help from the implemention
    func nilFoobar() -> Foo<Bar>? { return nil }
}

特别是foobar()的返回类型不需要指定Bar的占位符类型(后者又是通用Foo返回的占位符),因为这似乎被推断为与Self相同的占位符类型(U中的具体Self)。即,正如我所看到的,上述内容相当于(Xcode中foo()方法的Option-click描述除外)

struct Foo<T> { let foo: T }

struct Bar<U> {
    let bar: U

    func foobar() -> Foo<Bar<U>> {
        return Foo(foo: self)
    }

    func nilFoobar() -> Foo<Bar<U>>? { return nil }
}

由于返回类型Bar中的foobar()被推断为Bar<U>,我意识到这反过来应该禁止使用具体版本的泛型类型本身(我从来没有或有理由做的事情......)。正如预期的那样,这个理论认为:

struct Foo<T> { let foo: T }

struct Bar<U> {
    let bar: U

    func foobar() -> Foo<Bar<Int>> {
        return Foo(foo: Bar(bar: 1))
                              /* ^ error: 'Int' is not convertible to 'U' */
    }

    // concrete version of other generic type naturally allowed
    func fooint() -> Foo<Int> {
        return Foo(foo: 1)
    }
}

[†]而不是推断,也许一个捷径是更好的描述?因为它甚至在没有实际实现的情况下编译回到w.r.t.推断。

问题

我对在泛型类型中使用Self的具体版本没有任何用处,但有了一些想象力,我可以看到在某些角落情况下使用它。更重要的是,出于技术观点(和好奇心),我对为什么这似乎被设计不允许感兴趣。

  • 为什么我们不能在自己的实现中使用泛型类型的具体版本?由于它是一种具体的类型,我认为没有问题&#34;递归打字&#34;。这是一个设计决定吗?目前的限制?

我希望这个问题不属于基于意见的问题。鉴于斯威夫特的开放官方社区,也许有人可以通过官方联系的方式解释为什么设计应该禁止这样做(或者它只是当前的限制&#34;?)。

0 个答案:

没有答案