2016-10-16 2 views
0

Я пытаюсь преобразовать проект из Swift 2.3 Свифта 3.Swift 3,0 преобразования - содержит (_ :) в коллекции

Вот некоторые проблемы с contains(_:) из Collection:

extension Collection { 
    subscript (safe index: Index) -> Iterator.Element? { 
     return indices.contains(index) ? self[index] : nil 
    } 
} 

Ошибка является Missing argument label 'where:' in call

Я добавил where:, но теперь появляется другая ошибка:

Cannot convert value of type 'Self.Index' to expected argument type '(_) throws -> Bool'

От Swift руководства 3,0 языка, кажется, что он должен работать без ошибок:

if favoriteGenres.contains("Funk") { 
    print("I get up on the good foot.") 
} else { 
    print("It's too funky in here.") 
} 

ответ

2

В Swift 3, indices свойство Collection не Collection, а просто IndexableBase & Sequence. Который не имеет метода contains(_:), но только contains(where:) метод.

(. Из сгенерированного заголовка)

associatedtype Indices : IndexableBase, Sequence = DefaultIndices<Self> 

public var indices: Self.Indices { get } 

Вам может понадобиться, чтобы написать что-то вроде этого:

extension Collection { 
    subscript (safe index: Index) -> Iterator.Element? { 
     return (startIndex..<endIndex).contains(index) ? self[index] : nil 
    } 
} 

Или же вы можете вызвать contains(_:) метод Sequence where Iterator.Element : Equatable, с добавлением некоторые ограничения:

extension Collection 
where Indices.Iterator.Element: Equatable, Index == Indices.Iterator.Element 
{ 
    subscript (safe index: Indices.Iterator.Element) -> Iterator.Element? { 
     return indices.contains(index) ? self[index] : nil 
    } 
} 

Оба работают для простых массивов:

let arr = [1,2,3] 
print(arr[safe: 3]) //->nil 
print(arr[safe: 2]) //->Optional(3) 

Но я не уверен, что является более безопасным в целом.