Как использовать метод быстрого экземпляра с flatMap?

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

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

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

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

Но нам не нравятся Globals ;-) Поэтому я вместо этого расширяю строку:

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 так же, как и с глобальной функцией?


person Cortado-J    schedule 21.01.2019    source источник
comment
Спасибо @rmaddy. Изначально у меня был $ 0.double (), но мне понравилась простота .flatMap (double), поэтому я надеялся держаться подальше от $ 0.   -  person Cortado-J    schedule 21.01.2019
comment


Ответы (1)


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

Метод экземпляра - это метод карри, тип (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"]
person taka    schedule 21.01.2019
comment
Приятно @taka - аккуратно. И если я не хочу возиться с моим методом экземпляра, я могу сделать: extension String {static func double (_ string: String) - ›[String] {return string.double ()}}, а затем следовать вашему примеру. Спасибо. - person Cortado-J; 21.01.2019