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)})
是否可以在不使用
tail
arg的情况下重写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
。