Swift - делает тип func явным (в протоколе) - PullRequest
0 голосов
/ 19 сентября 2018

Предположим, у нас есть протокол с typealias как:

// common closure types
typealias Action = () -> Void
typealias Consumer<T> = (T) -> Void

// here starts the fun
typealias AsyncAction = (Action?) -> Void
typealias AsyncGetter<T> = (Consumer<T>?) -> Void
typealias AsyncSetter<T> = (T, Action?) -> Void

// make compiler and you happy
typealias Foo = Void
typealias Bar = Void

protocol FooBarDatabaseAccess {
    func doSomething()
    func doSomethingAsync(completion: Action?)//: AsyncAction
    func getFooAsync(completion: Consumer<Foo>?)//: AsyncGetter<Foo>
    func getBarAsync(completion: Consumer<Bar>?)//: AsyncGetter<Bar>
    func setBarAsync(value: Bar, completion: Action?)//: AsyncSetter<Bar>
}


Я хотел бы указать тип функции, подобный let / var объявлений с двоеточием, за которым следует присваиваемый тип:

/* -- let/var -- */

// implicitly typed as String, determined from initial assignment
let implicitString = ""

// explicitly typed as String, though initialisation is omitted here
let explicitString: String


/* -- func -- */

// implicitly typed as () -> Void, determined from argument/return type(s)
func implicitAction()

// explicitly typed as Action, compiler should complain if it does not conform to the type (alias)
???


Как этого добиться?

Возможный обходной путь - преобразовать его в объявление свойства, но это сбивает с толку:

var explicitAction: Action = { get }

1 Ответ

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

Поскольку Action является typealias, а не типом, swift не может их дифференцировать.

Как объясняется в документации :

После того, как псевдоним типа объявлен, псевдоним может использоваться вместо существующего типа везде в вашей программе.Существующий тип может быть именованным типом или составным типом.Псевдонимы типов не создают новые типы;они просто позволяют имени ссылаться на существующий тип.

Редактировать: Плохо, я думал, что вы хотите различать () -> Void и Action.Насколько я знаю, использование замыкания является единственным способом сделать это в быстром.

typealias Foo = (Int) -> Void

protocol FooBar {
  var foo: Foo { get }
}

class FooBarBaz: FooBar {
  var foo: Foo = { intValue in
    // ...
  }
}

Редактировать 2: Дополнительная информация:

Согласно Грамматика объявления функции , единственный способ *1027* объявления функции в явном виде - parameter-clause, который требует перечисления всех параметров в скобках:

объявление функции → заголовок функции имя функции обобщенное-параметр-условие опт сигнатура функции обобщенное-предложение-место опт тело-функции опт

функция-подпись → параметр-предложение броски опт функция-результат опция

-параметр параметра →() |(список параметров)

Очевидно, что невозможно объявить функцию с типом как сигнатуру без использования замыкания.

...