Как использовать быстрый метод Instance с flatMap? - PullRequest
0 голосов
/ 21 января 2019

Я могу определить глобальную функцию, которая удваивает строки:

func double(string: String) -> [String] {
  return [string, string]
}

И теперь я могу использовать это с flatMap

let animals = ["Ant", "Bear", "Cat"]
print( animals.flatMap(double) ) // ["Ant", "Ant", "Bear", "Bear", "Cat", "Cat"]

Но нам не нравятся глобальные переменные ;-)Вместо этого я расширяю строку:

extension String {
  func double() -> [String] {
    return [self, self]
  }
}

Но я не могу использовать это так же, как получаю:

print( animals.flatMap(String.double) ) // [(Function), (Function), (Function)]

Я вижу, что проблема в том, что типы разные.

print("type(of: double) = \(type(of: double))") //type(of: double) = (String) -> Array<String>
print("type(of: String.double) = \(type(of: String.double))") //type(of: String.double) = (String) -> () -> Array<String>

Я вижу, что String.double не подходит для flatMap, и это подчеркивается полученным предупреждением:

flatMapустарел: используйте compactMap (_ :) для случая, когда закрытие возвращает необязательное значение

Я думаю, это потому, что компилятор не находит подходящую перегрузку для flatMap.

Какя могу использовать метод экземпляра с flatMap так же, как я использовал глобальную функцию?

1 Ответ

0 голосов
/ 21 января 2019

С методом экземпляра вы не можете.

Метод экземпляра - это метод карри, тип (String) -> () -> Array<String> означает «метод берет строку и возвращает функцию, которая ничего не берет и возвращает массив строки».

Так что вы можете делать так, но не так, как пишете.

print(animals.flatMap{ String.double($0)() }) // ["Ant", "Ant", "Bear", "Bear", "Cat", "Cat"]

Вам нужен статический метод. Он просто принимает строку и возвращает массив строк.

extension String {
    static func double(_ string: String) -> [String] {
        return [string, string]
    }
}

print(animals.flatMap(String.double)) // ["Ant", "Ant", "Bear", "Bear", "Cat", "Cat"]
...