일반 함수를 명시 적으로 전문화 할 수 없습니다.
다음 코드에 문제가 있습니다.
func generic1<T>(name : String){
}
func generic2<T>(name : String){
generic1<T>(name)
}
generic1 (이름) 컴파일러 오류에 대한 결과는 "명시 적으로 일반적인 기능을 전문화 할 수 없습니다"
이 오류를 피할 수있는 방법이 있습니까? generic1 함수의 서명을 변경할 수 없으므로 (String)-> Void 여야합니다.
나는 또한이 문제가 있었고 내 사건에 대한 해결 방법을 찾았습니다.
이 기사에서 저자는 동일한 문제가 있습니다.
https://www.iphonelife.com/blog/31369/swift-programming-101-generics-practical-guide
그래서 문제는 컴파일러가 어떻게 든 T의 유형을 추론해야한다는 것입니다. 그러나 단순히 generic <type> (params ...)을 사용하는 것은 허용되지 않습니다.
일반적으로 컴파일러는 매개 변수 유형을 스캔하여 T 유형을 찾을 수 있습니다. T가 많은 경우에 사용되는 곳이기 때문입니다.
내 경우에는 내 함수의 반환 유형이 T 였기 때문에 약간 달랐습니다. 귀하의 경우에는 함수에서 T를 전혀 사용하지 않은 것 같습니다. 예제 코드를 단순화 한 것 같습니다.
그래서 다음과 같은 기능이 있습니다.
func getProperty<T>( propertyID : String ) -> T
그리고 예를 들어
getProperty<Int>("countProperty")
컴파일러는 나에게
Cannot explicitly specialize a generic function
따라서 컴파일러에 T 유형을 추론 할 수있는 또 다른 정보 소스를 제공하려면 반환 값이 저장되는 변수의 유형을 명시 적으로 선언해야합니다.
var value : Int = getProperty("countProperty")
이렇게하면 컴파일러는 T가 정수 여야한다는 것을 알 수 있습니다.
그래서 전반적으로 제네릭 함수를 지정하면 최소한 T를 매개 변수 유형이나 반환 유형에 사용해야한다는 의미라고 생각합니다.
스위프트 4.2
일반적으로 일반 함수를 정의하는 방법에는 여러 가지가 있습니다. 그러나 , 또는으로 T사용되어야 하는 조건을 기반 parameter으로합니다 return type.
extension UIViewController {
class func doSomething<T: UIView>() -> T {
return T()
}
class func doSomethingElse<T: UIView>(value: T) {
// Note: value is a instance of T
}
class func doLastThing<T: UIView>(value: T.Type) {
// Note: value is a MetaType of T
}
}
그 후에는 부를 T때 제공해야합니다 .
let result = UIViewController.doSomething() as UIImageView // Define `T` by casting, as UIImageView
let result: UILabel = UIViewController.doSomething() // Define `T` with property type, as UILabel
UIViewController.doSomethingElse(value: UIButton()) // Define `T` with parameter type, as UIButton
UIViewController.doLastThing(value: UITextView.self) // Define `T` with parameter type, as UITextView
참고 :
- http://austinzheng.com/2015/01/02/swift-generics-pt-1/
- https://dispatchswift.com/type-constraints-for-generics-in-swift-d6bf2f0dbbb2
솔루션은 클래스 유형을 매개 변수로 사용합니다 (Java에서와 같이)
컴파일러에게 그가 다루는 유형을 알리려면 클래스를 인수로 전달하십시오.
extension UIViewController {
func navigate<ControllerType: UIViewController>(_ dump: ControllerType.Type, id: String, before: ((ControllerType) -> Void)?){
let controller = self.storyboard?.instantiateViewController(withIdentifier: id) as! ControllerType
before?(controller)
self.navigationController?.pushViewController(controller, animated: true)
}
}
전화 :
self.navigate(UserDetailsViewController.self, id: "UserDetailsViewController", before: {
controller in
controller.user = self.notification.sender
})
정적 유형 (매개 변수로서의 문자열)이 있기 때문에 여기서 제네릭이 필요하지 않지만 제네릭 함수를 호출하려면 다른 함수를 호출하려면 다음을 수행 할 수 있습니다.
일반 방법 사용
func fetchObjectOrCreate<T: NSManagedObject>(type: T.Type) -> T {
if let existing = fetchExisting(type) {
return existing
}
else {
return createNew(type)
}
}
func fetchExisting<T: NSManagedObject>(type: T.Type) -> T {
let entityName = NSStringFromClass(type)
// Run query for entiry
}
func createNew<T: NSManagedObject>(type: T.Type) -> T {
let entityName = NSStringFromClass(type)
// create entity with name
}
제네릭 클래스 사용 (제네릭은 인스턴스 당 하나의 유형에 대해서만 정의 할 수 있으므로 유연성이 떨어짐)
class Foo<T> {
func doStuff(text: String) -> T {
return doOtherStuff(text)
}
func doOtherStuff(text: String) -> T {
}
}
let foo = Foo<Int>()
foo.doStuff("text")
일반 함수를 지정할 때 다음과 같이 T 유형의 일부 매개 변수를 지정해야한다고 생각합니다.
func generic1<T>(parameter: T) {
println("OK")
}
func generic2<T>(parameter: T) {
generic1(parameter)
}
and if you want to call handle() method, then you may do this by writing protocol, and specifying type constraint for T:
protocol Example {
func handle() -> String
}
extension String: Example {
func handle() -> String {
return "OK"
}
}
func generic1<T: Example>(parameter: T) {
println(parameter.handle())
}
func generic2<T: Example>(parameter: T) {
generic1(parameter)
}
so you may call this generic function with String:
generic2("Some")
and it will compile
I had a similar problem with my generic class function class func retrieveByKey<T: GrandLite>(key: String) -> T?.
I could not call it let a = retrieveByKey<Categories>(key: "abc") where Categories is a subclass of GrandLite.
let a = Categories.retrieveByKey(key:"abc") returned GrandLite, not Categories. Generic functions do not infer type based on the class that calls them.
class func retrieveByKey<T: GrandLite>(aType: T, key: String>) -> T? gave me an error when I tried let a = Categories.retrieveByKey(aType: Categories, key: "abc") gave me an error that it could not convert Categories.Type to GrandLite, even though Categories is a subclass of GrandLite. HOWEVER...
class func retrieveByKey<T: GrandLite>(aType: [T], key: String) -> T? did work if I tried let a = Categories.retrieveByKey(aType: [Categories](), key: "abc") apparently an explicit assignment of a subclass does not work, but an implicit assigment using another generic type (array) does work in Swift 3.
class UploadResult: Parsable{
...
}
func upload<T:Parsable>(type: T.Type, image: UIImage,
success:@escaping (_ error:ApiError?, _ result:T?)->Void )
{...}
UploadApi.upload(type: UploadResult.self, image: imageForUpload.image!) {...}
참고URL : https://stackoverflow.com/questions/27965439/cannot-explicitly-specialize-a-generic-function
'Programing' 카테고리의 다른 글
| 로드 된 모든 Spring Bean을 인쇄하십시오. (0) | 2020.10.07 |
|---|---|
| Pandas DataFrame의 행을 열 헤더로 변환, (0) | 2020.10.07 |
| 'DataFrame'개체에 'sort'속성이 없습니다. (0) | 2020.10.07 |
| jquery-chosen 드롭 다운 비활성화 (0) | 2020.10.07 |
| 노드 child_process를 사용하는 Stdout 버퍼 문제 (0) | 2020.10.07 |