Я пытаюсь реализовать общее хранение параметров конфигурации, используя строку типа класса в качестве словарного ключа.Идея состоит в том, что функция получения возвращает объект правильного типа.Каждый тип уникален в хранилище.Однако, когда я вызываю функцию, я получаю ошибку компилятора Swift и не уверен, как ее интерпретировать:
Compiler Error:
Cannot invoke 'retrieve' with an argument list of type '(type: Any.Type)
Я проверил документацию, и похоже, что метод type(of:)
долженвернуть класс времени выполнения, в то время как компилятор заставляет его выглядеть, как будто он жалуется, потому что думает, что я передаю тип Any
Как передать имя класса Swift в качестве параметра функции без использования экземпляра этогоclass?
func retrieve<T>(type: T.Type) -> T? {
let valueKey = String(describing: type)
print("retrieving: \(valueKey)")
return dictionary[valueKey] as? T
}
func update(with value: Any) {
let valueKey = String(describing: type(of: value))
print("Updating: \(valueKey)")
dictionary[valueKey] = value
}
let testCases: [Any] = [1, 2.0, "text"]
for testCase in testCases {
subject.update(with: testCase)
//Compiler Error: Cannot invoke 'retrieve' with an argument list of type '(type: Any.Type)
let t = type(of: testCase)
let retrieved = subject.retrieve(type: t)
//check for equality
}
//this works
expect(subject.retrieve(type: Int.self)).to(equal(1))
expect(subject.retrieve(type: Double.self)).to(equal(2.0))
expect(subject.retrieve(type: String.self)).to(equal("text"))
Я провел дополнительное тестирование и вижу, что мой массив не соответствует документации type (of:), , и эта функция возвращаеттот же объект, что и «Любой»:
func retrieve<T>(sample: T) -> T? {
let valueKey = String(describing: type(of: sample))
print("retrieving: \(valueKey)") //always retrieves same object "Any"
return dictionary[valueKey] as? T
}
Обновлено: Спасибо за ответы, чтобы прояснить - тестовые случаи предназначались для начала с простых типов, а затем переходили к более сложным классам.Фактическая реализация будет хранить совершенно уникальные экземпляры пользовательских типов, а не Strings или Ints.
let testCases: [Any] = [ConnectionConfig(...),
AccountID("testID"),
AccountName("testName")]
Тесты распознают универсальный характер функции получения и назначают соответствующие типы, о чем свидетельствует завершение кода:
expect(subject.retrieve(type: ConnectionConfig.self)?.ip).to(equal("defaultIP"))
expect(subject.retrieve(type: AccountID.self)?.value).to(equal("testId"))
Предполагаемое конечное использование в контексте RxSwift: предоставить универсальныйхранение в класс и позволяют ему извлекать соответствующие значения для параметров конфигурации.Если значения не существует, выдается ошибка, которая обрабатывается отдельным обработчиком ошибок:
class RxConfigConsumer: ConfigConsumer {
var connection: ConnectionConfig?
var accountID: AccountID?
init(with provider: ConfigProvider) {
connection = provider.retrieve(type: ConnectionConfig.self)
accountID = provider.retrieve(type: AccountID.self)
//etc
}
}