Тип проверки Swift на общий тип
У меня есть общая функция с 1 параметром и вы хотите проверить тип переданного параметра с общим типом. Что-то вроде этого:
func generic<T>(parameter: AnyObject) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
Но я не знаю, как назвать это
generic<String>("Hello")
Дает мне ошибку компилятора: "Нельзя явно специализировать общую функцию
Родовой ( "Hello" )
Ответы
Ответ 1
Вы не можете указать функции, какие типы ее общих заполнителей (в отличие от общей структуры). Он должен вывести их из контекста, например. его аргументы.
Один из способов сделать то, что вы хотите, - добавить еще один аргумент, относящийся к типу T
. Вместо того, чтобы передавать фиктивное значение, вы можете использовать метатип нужного типа:
func generic<T>(parameter: AnyObject, type: T.Type) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
let o: AnyObject = "hello"
generic(o, String.self) // true
generic(o, NSString.self) // also true
generic(o, Int.self) // false
Однако, я бы спросил вас, что вы думаете, что вы здесь достигаете? Вы существенно не сделали ничего, кроме как реализовать is
как функцию:
o is String // true
o is NSString // true
o is Int // false
Точка дженериков состоит в том, чтобы работать с аргументами в общем случае, но вы не даете функции какой-либо аргумент определенного типа, на самом деле выполняющий какую-либо работу (следовательно, неспособность сделать вывод).
Ответ 2
Эта ситуация не является кандидатом на общий. Вы просто просите протестировать объект против типа. Если это всегда будет AnyObject, вы можете попробовать что-то вроде этого:
func istest(parameter: AnyObject, whattype: AnyObject.Type) -> Bool {
if parameter.dynamicType === whattype.self {
return true
} else {
return false
}
}
Если вы действительно хотите получить общий тип, который вы можете специализировать, вы не можете специализировать функцию явно, поэтому вам придется обернуть свою функцию в общий тип и специализироваться на том, что:
struct Generic<T> {
func generic(parameter: AnyObject) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
}
let ok = Generic<String>().generic("howdy")
let ok2 = Generic<Int>().generic(1)
Но приведенный вами пример, как я уже сказал, не является хорошим кандидатом для этого. Помните, что общее решение разрешено во время компиляции - мы уже знаем, каким будет разрешенный тип. Таким образом, ваш тест бессмыслен, потому что вы уже знаете ответ. Вот почему я показал вам альтернативную функцию, в которой значение и тип неизвестны.
Ответ 3
Более общий подход:
struct Asserter<T>{
func generic(_ val:Any) -> Bool{
let type = type(of: val)
return T.self == type
}
}
_ = Asserter<String>().generic(2)//false
_ = Asserter<String>().generic("")//true
Ответ 4
Проверка, является ли общий тип каким классом.
protocol Some {}
class SomeClass: Some {}
class AClass: Some {}
func test(_ t: T) -> String {
if T.self == SomeClass.self {
return "Some Class"
} else {
return "Another Class"
}
}
print(test(SomeClass())) // Some Class
print(test(AClass())) // Another Class