当你想使用 index.advanceBy 时,你应该使用什么类型?
What type should you use when you want to use index.advanceBy?
我想在数组中的另一个对象附近找到一些对象。我以为我可以写一个这样的扩展方法,但我得到这个错误:
// Error: Cannot invoke 'advanceBy' with an argument list of type '(Int)'
Int
类型显然是错误的,但是 indexOf
方法需要一个 Self.Distance
参数,我不确定如何将其用作参数类型。
extension CollectionType where Generator.Element : Equatable {
func objectNear(object: Self.Generator.Element, indexModifier: Int) -> Self.Generator.Element? {
if let index = self.indexOf(object) {
let newIndex = index.advancedBy(indexModifier) // this doesn't work
//let newIndex = index.advancedBy(1) // but this this works
if self.indices.contains(newIndex) {
return self[newIndex]
}
}
return nil
}
}
(如果有更 Swifty 的方法,我很乐意听到,但无论如何我都想了解以上内容。)
CollectionType
有方法
public func indexOf(element: Self.Generator.Element) -> Self.Index?
并符合
public protocol Indexable {
typealias Index : ForwardIndexType
// ...
}
终于,ForwardIndexType
有了方法
public func advancedBy(n: Self.Distance) -> Self
因此正确的类型是 Index.Distance
:
func objectNear(object: Self.Generator.Element, indexModifier: Index.Distance) -> Self.Generator.Element? { ... }
但请注意,将索引推进到 endIndex
以上可能会崩溃,
例如对于字符集:
let c = "abc".characters
print(c.objectNear("b", indexModifier: 1)) // Optional("c")
print(c.objectNear("b", indexModifier: 2)) // nil
print(c.objectNear("b", indexModifier: 3)) // fatal error: can not increment endIndex
一个安全的变体是:
func objectNear(object: Generator.Element, indexModifier: Index.Distance) -> Generator.Element? {
if let index = indexOf(object) {
if indexModifier > 0 && index.distanceTo(endIndex) <= indexModifier {
return nil
}
if indexModifier < 0 && startIndex.distanceTo(index) < -indexModifier {
return nil
}
return self[index.advancedBy(indexModifier)]
}
return nil
}
或者,如果您只需要用于集合的方法
由Int
(例如Array
)索引,那么您可以定义
extension CollectionType where Generator.Element : Equatable, Index == Int {
func objectNear(object: Generator.Element, indexModifier: Int) -> Generator.Element? {
if let index = self.indexOf(object) {
let newIndex = index + indexModifier
if indices.contains(newIndex) {
return self[newIndex]
}
}
return nil
}
}
我想在数组中的另一个对象附近找到一些对象。我以为我可以写一个这样的扩展方法,但我得到这个错误:
// Error: Cannot invoke 'advanceBy' with an argument list of type '(Int)'
Int
类型显然是错误的,但是 indexOf
方法需要一个 Self.Distance
参数,我不确定如何将其用作参数类型。
extension CollectionType where Generator.Element : Equatable {
func objectNear(object: Self.Generator.Element, indexModifier: Int) -> Self.Generator.Element? {
if let index = self.indexOf(object) {
let newIndex = index.advancedBy(indexModifier) // this doesn't work
//let newIndex = index.advancedBy(1) // but this this works
if self.indices.contains(newIndex) {
return self[newIndex]
}
}
return nil
}
}
(如果有更 Swifty 的方法,我很乐意听到,但无论如何我都想了解以上内容。)
CollectionType
有方法
public func indexOf(element: Self.Generator.Element) -> Self.Index?
并符合
public protocol Indexable {
typealias Index : ForwardIndexType
// ...
}
终于,ForwardIndexType
有了方法
public func advancedBy(n: Self.Distance) -> Self
因此正确的类型是 Index.Distance
:
func objectNear(object: Self.Generator.Element, indexModifier: Index.Distance) -> Self.Generator.Element? { ... }
但请注意,将索引推进到 endIndex
以上可能会崩溃,
例如对于字符集:
let c = "abc".characters
print(c.objectNear("b", indexModifier: 1)) // Optional("c")
print(c.objectNear("b", indexModifier: 2)) // nil
print(c.objectNear("b", indexModifier: 3)) // fatal error: can not increment endIndex
一个安全的变体是:
func objectNear(object: Generator.Element, indexModifier: Index.Distance) -> Generator.Element? {
if let index = indexOf(object) {
if indexModifier > 0 && index.distanceTo(endIndex) <= indexModifier {
return nil
}
if indexModifier < 0 && startIndex.distanceTo(index) < -indexModifier {
return nil
}
return self[index.advancedBy(indexModifier)]
}
return nil
}
或者,如果您只需要用于集合的方法
由Int
(例如Array
)索引,那么您可以定义
extension CollectionType where Generator.Element : Equatable, Index == Int {
func objectNear(object: Generator.Element, indexModifier: Int) -> Generator.Element? {
if let index = self.indexOf(object) {
let newIndex = index + indexModifier
if indices.contains(newIndex) {
return self[newIndex]
}
}
return nil
}
}