【问题标题】:"Never" Type as Default Type for Multi-Generic Initialization“从不”类型作为多泛型初始化的默认类型
【发布时间】:2020-12-25 15:29:04
【问题描述】:

问题

我的目标是以某种方式初始化一个类似这样的通用对象:

struct SomeStruct<A, B> where A: View, B: View {
    let a: A?
    let b: B?
    
    init(a: A? = nil, b: B? = nil) {
        self.a = a
        self.b = b
    }
}

let someStruct: SomeStruct = .init(a: Color.red)

但是,这个 sn-p 会抛出一个错误:

Generic Parameter 'B' Couldn't Be Inferred

备选方案 #1:钻石符号

另一种选择是在菱形符号中指定Never 类型:

let someStruct: SomeStruct<Color, Never> = .init(a: Color.red)

但这是一个笨拙的解决方案,因为我不想显式传递类型。

备选方案 #2:受约束的初始化器

另一种冗长的替代方法是编写自定义初始化程序,通过指定 Never 类型省略每种类型:

struct SomeStruct<A, B> where A: View, B: View {
    let a: A?
    let b: B?
}

extension SomeStruct where A == Never {
    init(b: B) {
        self.a = nil
        self.b = b
    }
}

extension SomeStruct where B == Never {
    init(a: A) {
        self.a = a
        self.b = nil
    }
}

extension SomeStruct where A == Never, B == Never {
    init() {
        self.a = nil
        self.b = nil
    }
}

let someStruct: SomeStruct = .init(a: Color.red)

但正如您所见,这需要大量重复的代码。因此,如果我有一个 10 种泛型类型的对象,这可能会变得一团糟。

问题

简而言之,我正在寻找一种方法来保留一个简单的初始化程序,如问题部分所示。有没有办法为参数提供默认类型 (Never),因为您通常会为该参数提供默认值?

【问题讨论】:

    标签: swift generics swiftui generic-programming


    【解决方案1】:

    这不是解决方案,而是 Combine 模式重用(由 Apple SDK 本身完成)...

    代替

    让 someStruct: SomeStruct = .init(a: Color.red)

    我建议使用

    let someStruct = SomeStruct<Color, Never>(a: Color.red)
    

    因为这是 Apple 自己广泛使用的符号,例如 AnySubscriber&lt;Color, Never&gt;AnyPublisher&lt;Color, Never&gt; 等。

    let subject = CurrentValueSubject<CGFloat, Never>(0)  // exactly your case
    

    注意:对于 10 种类型,请查看 ViewBuilder

    【讨论】:

      【解决方案2】:

      有没有办法为参数提供默认类型(从不),如 您通常会为该参数提供默认值吗?

      没有。但是每个人都想要它(我问过他们),虽然 Swift 论坛上已经有关于它的活动,但它还没有实现。

      示例线程: https://forums.swift.org/t/draft-allow-default-value-for-parameters-in-generic-clause/11200

      因此,如果我有一个 10 种泛型类型的对象,这可能会变得一团糟。

      是的,这就是现状。你的问题,还有lack of variadics,才是大问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-06
        • 1970-01-01
        • 2016-11-14
        • 1970-01-01
        • 2017-12-30
        • 1970-01-01
        • 2019-03-16
        • 1970-01-01
        相关资源
        最近更新 更多