2014-08-03 4 views
0

я играл с обобщениями и имею эту функцию, которая принимает массив и проверяет, если он содержит заданное значение ...Swift Дженерик с любым

func finder<T:Equatable>(array:[T], valueToFind:T) -> Int? { 
    for(index, value) in enumerate(array) { 
     if(value == valueToFind) { 
      return index 
     } 
    } 
    return nil 
} 

Если я использую его с помощью этого тестового массива, это работает отлично и возвращает правильный индекс.

var testArray = ["Dog", "Cat", "Mouse", "Tiger"] 

finder(testArray, "Cat") 

Аналогично работает для этого тестового массива чисел:

var testArray = [1, 2] 

finder(testArray, 1) 

Однако, когда у меня есть тестовый массив, как это со строками и пронумерована, (я предполагаю Inferred быть типа Any, то функция не работает, и я получаю ошибку компиляции: «? Int»

var testArray = ["Dog", "Cat", "Mouse", "Tiger", 2] 

finder(testArray, "Cat") 

не удается преобразовать тип выражения с типа «StringLiteralConvertible» Почему это?

+0

Интересно, что даже ты gh отображается ошибка, она по-прежнему работает так, как вы ожидали (тестирование на игровой площадке). – jtbandes

+0

@jtbandes интересный - для меня это не работает! Я на Beta 4. – Woodstock

+0

На самом деле, он работает, если вы помещаете массив в строку, но то, что не работает для меня, - это сохранение массива как переменной (без явного указания 'Any') – jtbandes

ответ

2

Any и AnyObject не соответствует Equatable поэтому они не могут passed.As у вас есть определить общие, как [T] и подтверждает <T:Equatable> где T repersents определенного типа так AnyObject и Any не конкретный тип.

Как ниже код не будет отображаться сообщение об ошибке, потому что T не соответствующую Equatable и действительно пройти [Any]

func finder<T>(array:[T], valueToFind:T) -> Int? { 
    for(index, value) in enumerate(array) { 
     //code 
     //You can not compare here value == valueToFind .T should be Equatable for comparison 
    } 
    return nil 
} 


var testArray = ["Dog", "Cat", "Mouse", "Tiger",2] //It will refer as Any 

finder(testArray, 2) //not have any errors and it is asuming `testArray` as `Any` 

Вы также можете увидеть дальнейший анализ, как T требуют, чтобы быть определенного типа

Так вам необходимо указать конкретный тип для дженериков, которые перевозятся T. Как вы проходите TvalueToFind как String так array также должен быть тип String, как это показано в погрешности ниже два statements.If вы передаете Int чем он будет показывать 'IntegerLiteralConvertible' ошибку

finder<T:Equatable>(array:[T], valueToFind:T) //Here both `T` should be refer to same type either String or Int 

var testArray = ["Dog", "Cat", "Mouse", "Tiger",2] 


finder(testArray, "Cat") //Shows error Cannot convert the expression's type 'Int?' to type 'StringLiteralConvertible' 

finder(testArray, 2) //Shows error Cannot convert the expression's type 'Int?' to type 'IntegerLiteralConvertible' 

или удалить другой параметр теперь он будет показывать Equatable ошибки, как это преобразование testArray в Any, который не соответствует Equatable, но в этом он показывает конкретную ошибку

func finder<T:Equatable>(array:[T]) -> Int? { 

    return nil 
} 

var testArray = ["Dog", "Cat", "Mouse", "Tiger",2] 

finder(testArray) //Shows error Cannot convert the expression's type 'Int?' to type 'Equatable' 

так что в этом коде принимаемой testArray в Any

Смежные вопросы