#swift
#swift
Вопрос:
Например, функция вернет значение типа T
, такого же, как у атрибута экземпляра, следующим образом:
// how to write the type T
func executeTask() -> T {
// build and run a task
let task = Process()
...
task.launch()
let status: T = task.terminationStatus
return status
}
-[Process terminationStatus]
возвращает Int32
значение в Swift, но однажды тип может измениться.
Вместо определения явного возвращаемого типа, например func executeTask() -> Int32 {...}
, есть ли лучший способ определить возвращаемый тип всегда таким же, как атрибут экземпляра?
Комментарии:
1. Если возвращаемый тип
terminationStatus
изменяется, у вас возникают более серьезные проблемы, о которых нужно беспокоиться, чем изменение возвращаемого типаexecuteTask
, а именно, что весь ваш код, который зависит отexecuteTask
возврата anInt32
, сломается.2. Что такое «атрибут экземпляра»? Что означает «всегда совпадает с атрибутом экземпляра»? И что этот код пытается сделать? Использование
T
предполагает универсальную, но это не универсальная функция, поэтому это не имеет смысла.
Ответ №1:
Я бы подумал о добавлении явного пользовательского типа для возвращаемого значения таким образом, чтобы его расширением можно было управлять и не затрагивать уже существующий код.
Вот пример использования enum
enum TaskStatus {
case code(Int)
// case value(String) // << ex. add in future
}
func executeTask() -> TaskStatus {
// build and run a task
let task = Process()
//...
task.launch()
let status = task.terminationStatus
return .code(status)
}
Комментарии:
1.
Enum
Здесь лучше, чемtypealias
?2. Изменение типов повлияет на существующий код (ошибки компиляции, приведение, логика и т. Д.), Добавление нового регистра в enum не повлияет. Поэтому я бы сказал, что да, это более уместно.
Ответ №2:
Может быть другой подход, который, по крайней мере, поможет вам не нарушать ваш код, когда вы решите изменить возвращаемый тип.
Вы можете объявить специальный класс для статуса задачи, состоящий из всех форматов, которые вам нужны или понадобятся в будущем. Вы также можете создать инициализатор, который будет приносить Any
значение и преобразовывать его во все нужные вам типы. Вот так:
class TaskStatus {
var int32status: Int32?
init(with value: Any) {
switch value {
case is Int32:
int32status = value
case is Int:
int32status = Int32(value)
default:
print("Task Status initialization for type (String(describing: value)) is not prepared")
}
}
}
И в вашем коде:
func executeTask() -> TaskStatus {
// build and run a task
let task = Process()
...
task.launch()
let status: T = task.terminationStatus
return TaskStatus(with: status)
}