tail对于数组:

private extension Array {
    var tail: Array { get { return Array(dropFirst(self)) } }
}

以下是Sliceable的通用版本:
public func tail<S: Sliceable>(sequence: S, initializer: ((S.SubSlice) -> S)) -> S {
    return initializer(dropFirst(sequence))
}
let s = tail("12", {String($0)})

是否可以在不使用tailarg的情况下重写genericinitializer
也就是说,通过序列类型(initializer或其他类型)调用S()

最佳答案

对于可切片类型,T可以与T.SubSlice不同。
例如T,但String.SubSlice == String
您可以定义一个协议来描述所有类型
从自己的子许可创建:

public protocol CreatableFromSubslice : Sliceable {
    init(_ subslice : Self.SubSlice)
}

即使大多数(全部?)内置的可切片类型可以从其自身创建
子片,您仍然必须告诉编译器
扩展名:
extension String : CreatableFromSubslice { }
extension Array : CreatableFromSubslice { }
// ...

Array.SubSlice == ArraySlice<T>可定义为
public func tail<S: CreatableFromSubslice>(slice: S) -> S {
    return S(dropFirst(slice))
}

例子:
let s = tail("12")
println(s) // "2"

let a = tail([1, 2, 3])
println(a) // [2, 3]

对于与其子层类型相等的类型,可以定义
public func tail<S: Sliceable where S.SubSlice == S >(slice: S) -> S {
    return dropFirst(slice)
}

这可以应用于tail(),但不能应用于String

07-28 06:28