Как мне заставить функцию принимать строку или массив строк?

#swift

#swift

Вопрос:

Я чувствую, что это «универсальная» вещь, но я не могу понять, как это делают другие? Я почти уверен, что в Typescript я просто делаю String|String[] , но не уверен, как это работает в Swift. Вот моя попытка:

 func HiWorld(passedVar: String|[String]){
   print(passedVar)
}
 

или

 func HiWorld<T, String|[String]>(passedVar: T){
   print(passedVar)
}
 

Комментарии:

1. Возможно, стоит рассмотреть возможность сохранения только этой String версии. Array.map(_:) и Array.forEach(_:) позволяет преобразовывать каждую функцию, которая принимает один элемент, в функцию, которая может принимать массив элементов, без необходимости многократных перегрузок

2. @Alexander спасибо за рекомендацию. Для моего варианта использования я в итоге создал две необязательные переменные в одной функции, которая принимает строку? и тот, который принимает [Строку]? и отклонение, если оба равны нулю. Конечно, это немного странный вариант использования, и было бы безопаснее, если бы я просто выполнил рекомендацию функции-оболочки, как предложил Роб.

3. and rejecting if both are nil Вероятно, это неуместная ответственность. Разворачивание опций должно выполняться на стороне вызывающего абонента, а не на стороне вызываемого абонента.

Ответ №1:

То, что вы описываете, является перегрузкой. Вы просто выражаете это как две функции, где одна привязывается к более общей версии.

 // Specialized version; a one-element list
func hiWorld(passedVar: String) {
   hiWorld(passedVar: [passedVar])
}

// general version; list of any length
func hiWorld(passedVar: [String]) {
   print(passedVar)
}
 

(На практике часто именно так вы в конечном итоге реализуете ее и в TypeScript, поскольку обычно вы не можете делать одно и то же со всеми типами. Ваш print пример — очень особый и вводящий в заблуждение случай.)

Синтаксис, который вы описываете, является алгебраическим типом данных, и Swift не поддерживает этот синтаксис напрямую. Хотя это может быть удобным сокращением, Swift обычно предпочитает использовать явное перечисление или протокол в случаях, когда такая перегрузка не имеет смысла.

Комментарии:

1. Спасибо за контекст, очень полезно.