2017-01-31 2 views
2

Моя цель - использовать typealias как напоминание одного слова, «прикрепленное» к объявлению функции. Скажем,Аннотирование всего объявления функции с помощью typealias

typealias VoidToVoid =() ->() 

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

let f : VoidToVoid = { return } 
assert(f is VoidToVoid) 

Однако, это не кажется, самым обычным способом объявления функций. Я надеялся найти способ сообщить читателю, что функция, объявленная как f′ ниже, должна быть типа VoidToVoid и с использованием этого имени.

(Но без читателя, имеющих сделать вывод, или думать, или ждать компилятора, чтобы сказать ему или ей о типе. Обострение ситуации, компилятор не может знать имя типа псевдонима я хотел с f′ и, скорее всего, выводить сообщения о том, голом типе, а не псевдоним.)

func f′() : VoidToVoid { // tentative syntax 
    return 
} 

Могу ли я получить там вообще?

Редактировать: Есть два конца, в которых должен использоваться псевдоним типа. На одном конце, теперь это возможно:

func giveMeAClosure(_ f: VoidToVoid) { 
    f() 
} 

На другом конце, будучи VoidToVoid подразумевается:

func canBeGivenAsClosure() { 
    // ... 
} 

То есть, где canBeGivenAsClosure объявляется, это правда, но не очевидно, что есть соединение между двумя концами через VoidToVoid. Это отличается от случая let, который может содержать «VoidToVoid» в качестве аннотации типа.

ответ

2

Замыкание безымянные выражения закрытия, поэтому мы можем использовать функцию типа typealias указать тип закрытия, даже для затворов, которые имеют непустой список аргументов.

typealias VoidToVoid =() ->() 
typealias IntToVoid = (Int) ->() 

        // unnamed closure expressions 
let f: VoidToVoid = { print("foo") } 
let g: IntToVoid = { print($0) } 

Здесь следует отметить, что f и g в этих exaples не являются функциями: они просто неизменные свойства, содержат ссылки на (хранилище поддержки) неназванные затворы, указанные в момент их объявления.

Функция, с другой стороны, является частным случаем замыкания; закрытие с именем. Более того, любая функция с непустым списком аргументов должна указывать во внутренних (и необязательно) и внешних именах параметров в своем заявлении. Функция типа typealias, однако, может не содержать аргументы метки для ее имен параметров:

typealias IntToVoid = (a: Int) ->() 
/* Error: function types cannot have argument 
      label 'a'; use '_' instead */ 

Это означает, что тип функция typealias может не представляется возможным использовать замену для комбинированного параметра и типа возвращаемого Декларативной части (даже в случае () ->()).

Подробнее см., Например,:

Затворы

...

Глобальные и вложенные функции, как и введены в Functions, на самом деле являются специальные случаи закрытия. Закрытия берут одну из трех форм:

  • Глобальные функции - это замыкания, которые имеют имя и не фиксируют никаких значений.
  • Вложенные функции - это замыкания, которые имеют имя и могут захватывать значения из их закрывающей функции.
  • Выражения закрытия - это неназванные замыкания, написанные в легком синтаксисе, которые могут захватывать значения из окружающего их контекста.

На другой ноте, вы можете естественно тест тип данной функции в некоторой существующей функции типа typealias.

typealias VoidToVoid =() ->() 
typealias IntToVoid = (Int) ->() 

func f() ->() {} 
func g(_ a: Int) ->() { _ = a } 

print(f is VoidToVoid) // true 
print(g is IntToVoid) // true 
+0

Тем не менее, с точки зрения типов, две функции, принимающие '' Int' в Void' могут использовать все виды различных имен в их _function-name_ и _function-signature_ и по-прежнему передаются как значения, где ожидается неназванный «IntToVoid». Это то, что я хотел бы выразить. – B98

+0

@ B98 Прежде всего обратите внимание, что замыкания являются ссылочными типами, поэтому ни функции, ни неназванные замыкания не передаются по значению, а скорее по ссылке. Поскольку я понял ваш вопрос, вы бы хотели использовать тип функции 'typealias', чтобы полностью заменить функцию -функцию-signature_ функции: это невозможно. Следуя грамматике функции. decl., _function-signature_ содержит _parameter-clause_, которое в свою очередь (для не-void) содержит _parameter-list_ с числом _parameter_: s, а для грамматики для этих ** требуется ** a _local-parameter-name_ , которые могут отсутствовать в «титалиасах»; ... – dfri

+0

... простой 'typealias' содержит значение _type-annotation_ (вторая требуемая часть) в каждом _параметре_. – dfri

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