初始化器避免将空数组作为参数

Initializer avoiding an empty array as argument

我有一个初始化程序它需要一个值

internal init(value pValue: T) { ... }

现在我有一个便捷初始化程序,可以将数组转换为我的类型。但是那个数组可能不为空(因为它需要一个值才有意义,所以前面有指定的初始化程序)。

internal convenience init(array pArray: [T]) {
    guard !pArray.isEmpty else {
        // it is not correct to init without at least one value
        return // or assert
    } // compiler error because there is no init call

    .. // init with non-empty array
}

有什么解决方案可以让使用该界面的人不会感到惊讶并且仍然具有良好的可用性?

这里的障碍是,在初始化器中,每条路径都需要调用初始化器。

我认为有意义的解决方案是,当初始化器获取一个空数组作为参数时,创建具有该类型的任意值的类型 T

self.init(T())

但我无法创建 T,因为我不知道 T 的初始值设定项。

而且我不能简单地使用

self.init(0)

因为编译器需要类型为 T 的初始化程序。


我确实将它实现为静态方法并且它有效(因为我可以选择不使用 init),但我希望它作为非静态方法

我也确实将它实现为可变参数并且它可以工作,但是这对于许多参数来说非常不方便

也许你可以使用可失败的初始值设定项return nil 如果数组为空:

class Type<T> {
    init?(array pArray: [T]) {
        guard !pArray.isEmpty else {
            return nil
        }

        // ...
    }

    init(value pValue: T) {
        // ...
    }
}

A failable init 是答案,但你需要声明 <T>,并且你需要调用 main init -

class A { // or class A<T> 
    var count = 0

    init() {            
    }

    internal convenience init?<T>(array pArray: [T]) { // <T> not needed if declared at Class level
        guard !pArray.isEmpty else {
            // it is not correct to init without at least one value
            return nil
        }

        // init with non-empty array
        self.init()
        self.count = pArray.count
    }
}

let n:[String] = ["a"]
if let a = A(array: n) {
    print("\(a.count)")
} else {
    print("nil")
}