What is the `_base` property of an ReverseRandomAccessCollection?

北慕城南 提交于 2020-01-03 20:58:27

问题


Is it good practice to use the _base property to access the elements of a ReverseRandomAccessCollection?

let myArray = [1, 2, 3]
print(myArray.first) // returns 1

print(myArray.reversed().first) // returns 3
print(myArray.reversed()._base.first) // return 1, which is the underlying base array

回答1:


A ReverseRandomAccessCollection (you can see its full implementation here) is a simply a wrapper that presents a reversed view onto an underlying RandomAccessCollection (this saves from having to do an O(n) walk through it).

The way this is achieved is through keeping an _base property of the underlying collection, and then implementing the RandomAccessCollection protocol in order to present a reversed view onto it, such reversing index traversal (comments mine):

public struct ReversedRandomAccessCollection<
  Base : RandomAccessCollection
> : RandomAccessCollection {

    public let _base: Base // the underlying collection to present the reversed view on

    // ...

    public var startIndex: Index { // startIndex accesses endIndex of _base
        return ReversedRandomAccessIndex(_base.endIndex)
    }

    public var endIndex: Index { // endIndex accesses startIndex of _base
        return ReversedRandomAccessIndex(_base.startIndex)
    }

    public func index(after i: Index) -> Index { // index(after:) gets the index(before:)
        return ReversedRandomAccessIndex(_base.index(before: i.base))
    }

    public func index(before i: Index) -> Index { // index(before:) gets the index(after:)
        return ReversedRandomAccessIndex(_base.index(after: i.base))
    }

    public func index(_ i: Index, offsetBy n: IndexDistance) -> Index { 
        // index offset is simply made negative,
        // then forwarded to base's index(_:offsetBy:) method
        return ReversedRandomAccessIndex(_base.index(i.base, offsetBy: -n))
    }

    // ...
}

As the _base property is public, there's nothing to stop you from using it. However, underscore prefixed properties and methods are used to indicate implementation details that are not part of the public API – as they're often not designed to be used directly, and are subject to change without warning.

In this case you can simply work with the array before you call reversed() – it will be the same as _base (until you mutate it). Therefore, instead of doing:

myArray.reversed()._base.first

you should just do:

myArray.first

which will yield the same result.




回答2:


As mentioned in comments better not use _ methods, there is no need for that risk. In Swift 3 reversed() returns wrapper ReversedRandomAccessCollection to access array as if it was reversed - without the need to allocate new array, while reverse() mutates existing array:

var myArray = [1, 2, 3]
myArray.reverse()
print(myArray.first) // returns 3
print(myArray.reversed().first) // returns 1
print(myArray.reversed()._base.first) // return 3

Note: you can call reverse() on var only



来源:https://stackoverflow.com/questions/39547399/what-is-the-base-property-of-an-reverserandomaccesscollection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!