Swift: неоднозначная ссылка на член 'карту' - PullRequest
0 голосов
/ 01 сентября 2018

Я читаю "Язык программирования Swift 4.2". В начале главы, стр. 23, у меня есть следующее требование:

Переписать замыкание, чтобы вернуть ноль для всех нечетных чисел

И мое решение:

let myArray: [Int] = [1, 2, 3, 4, 5]

myArray.map({ (number: Int) in 
   if number % 2 != 0 {
       return 0
   } else {
       return number
   }
})

Но у меня есть следующая ошибка:

Неоднозначная ссылка на член 'map'

Я действительно не понимаю, почему я не прав, почему мой myArray не может ссылаться на члена map? Не могли бы вы дать мне объяснение этой ошибки и правильное решение для этого? Спасибо!

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Вместо того, чтобы аннотировать тип параметра, вы должны указать тип возврата замыкания

let myArray = [1, 2, 3, 4, 5] // You don't even need to annotate the array, the compiler knows the type.

let result = myArray.map({ number -> Int in
    if number % 2 != 0 {
        return 0
    } else {
        return number
    }
})

Или с синтаксисом замыкающего замыкания и сокращенными именами аргументов. В этом случае компилятор может вывести все, что угодно

let result = myArray.map { $0 % 2 != 0 ? 0 : $0 }
0 голосов
/ 01 сентября 2018

Сделайте это менее двусмысленным, указав тип возврата с помощью as [Int]:

myArray.map({ (number: Int) in 
   if number % 2 != 0 {
       return 0
   } else {
       return number
   }
}) as [Int]

Или:

let result: [Int] = myArray.map({ (number: Int) in
    if number % 2 != 0 {
        return 0
    } else {
        return number
    }
})
print(result) //[0, 2, 0, 4, 0]

Как отмечает vadian : Неопределенность проистекает из того факта, что общий тип возвращаемого значения в замыкании не может быть выведен.

Чтобы понять, как компилятор определяет тип возврата замыкания, давайте вернемся к синтаксису замыкания:

let myClosure: returnType = { (params) -> returnType in
    statements
}

Здесь тип myClosure равен returnType. И он установлен в двух местах: после : и после ->. Вы можете использовать вывод типа, удалив returnType из одного из двух мест, но не из обоих.

Чтобы вы могли удалить его из фигурных скобок (как в коде выше):

let result: [Int] = myArray.map({ (number: Int) in

Или сразу после имени переменной и указания типа возврата замыкания внутри фигурных скобок:

let result = myArray.map({ (number: Int) -> Int in
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...