programing

Swift에서 일반 프로토콜을 만드는 방법은 무엇입니까?

muds 2023. 8. 14. 23:12
반응형

Swift에서 일반 프로토콜을 만드는 방법은 무엇입니까?

제네릭 입력을 받고 제네릭 값을 반환하는 방식으로 프로토콜을 만들고 싶습니다.

이것은 제가 지금까지 시도한 것이지만, 구문 오류가 발생합니다.

선언되지 않은 식별자 T를 사용합니다.

내가 뭘 잘못하고 있는 거지?

protocol ApiMapperProtocol {
    func MapFromSource(T) -> U
}

class UserMapper: NSObject, ApiMapperProtocol {
    func MapFromSource(data: NSDictionary) -> UserModel {
        var user = UserModel() as UserModel
        var accountsData:NSArray = data["Accounts"] as NSArray     
        return user
    } 
}

프로토콜에 따라 약간 다릅니다.Apple 설명서의 "관련 유형"을 참조하십시오.

다음은 예제에서 사용하는 방법입니다.

protocol ApiMapperProtocol {
    associatedtype T
    associatedtype U
    func MapFromSource(_:T) -> U
}

class UserMapper: NSObject, ApiMapperProtocol {
    typealias T = NSDictionary
    typealias U = UserModel

    func MapFromSource(_ data:NSDictionary) -> UserModel {
        var user = UserModel()
        var accountsData:NSArray = data["Accounts"] as NSArray
        // For Swift 1.2, you need this line instead
        // var accountsData:NSArray = data["Accounts"] as! NSArray
        return user
    }
}

프랑코의 대답을 조금 더 자세히 설명하자면, 만약 당신이 특정한 방법을 사용하는 방법을 만들고 싶다면.ApiMapperProtocol당신은 다음과 같이 합니다.

protocol ApiMapperProtocol {
    associatedtype T
    associatedtype U
    func mapFromSource(T) -> U
}

class UserMapper: NSObject, ApiMapperProtocol {
    // these typealiases aren't required, but I'm including them for clarity
    // Normally, you just allow swift to infer them
    typealias T = NSDictionary 
    typealias U = UserModel

    func mapFromSource(data: NSDictionary) -> UserModel {
        var user = UserModel()
        var accountsData: NSArray = data["Accounts"] as NSArray
        // For Swift 1.2, you need this line instead
        // var accountsData: NSArray = data["Accounts"] as! NSArray
        return user
    }
}

class UsesApiMapperProtocol {
    func usesApiMapperProtocol<
        SourceType,
        MappedType,
        ApiMapperProtocolType: ApiMapperProtocol where
          ApiMapperProtocolType.T == SourceType,
          ApiMapperProtocolType.U == MappedType>(
          apiMapperProtocol: ApiMapperProtocolType, 
          source: SourceType) -> MappedType {
        return apiMapperProtocol.mapFromSource(source)
    }
}

UsesApiMapperProtocol이제는 수락만 보장됩니다.SourceType주어진 것과 양립할 수 있는ApiMapperProtocol:

let dictionary: NSDictionary = ...
let uses = UsesApiMapperProtocol()
let userModel: UserModel = uses.usesApiMapperProtocol(UserMapper()
    source: dictionary)

제네릭을 가지고 있고 또한 이렇게 선언하도록 하기 위해.let userMapper: ApiMapperProtocol = UserMapper()제네릭 요소를 반환하는 프로토콜을 준수하는 제네릭 클래스가 있어야 합니다.

protocol ApiMapperProtocol {
    associatedtype I
    associatedType O
    func MapFromSource(data: I) -> O
}

class ApiMapper<I, O>: ApiMapperProtocol {
    func MapFromSource(data: I) -> O {
        fatalError() // Should be always overridden by the class
    }
}

class UserMapper: NSObject, ApiMapper<NSDictionary, UserModel> {
    override func MapFromSource(data: NSDictionary) -> UserModel {
        var user = UserModel() as UserModel
        var accountsData:NSArray = data["Accounts"] as NSArray     
        return user
    } 
}

이제 다음을 참조할 수 있습니다.userMapper한 사람으로서ApiMapper에 대한 구체적인 구현이 있는.UserMapper:

let userMapper: ApiMapper = UserMapper()
let userModel: UserModel = userMapper.MapFromSource(data: ...)

일반 프로토콜을 만들고 사용하는 방법:

protocol Generic {
    
    associatedtype T
    associatedtype U

    func operation(_ t: T) -> U
}


// Use Generic Protocol

struct Test: Generic {

    typealias T = UserModel
    typealias U = Any
    
    func operation(_ t: UserModel) -> Any {
        let dict = ["name":"saurabh"]
        return dict
    }
}

템플릿 메서드를 유형 삭제...와 함께 사용할 수 있습니다.

protocol HeavyDelegate : class {
  func heavy<P, R>(heavy: Heavy<P, R>, shouldReturn: P) -> R
}  

class Heavy<P, R> {
    typealias Param = P
    typealias Return = R
    weak var delegate : HeavyDelegate?  
    func inject(p : P) -> R? {  
        if delegate != nil {
            return delegate?.heavy(self, shouldReturn: p)
        }  
        return nil  
    }
    func callMe(r : Return) {
    }
}
class Delegate : HeavyDelegate {
    typealias H = Heavy<(Int, String), String>

    func heavy<P, R>(heavy: Heavy<P, R>, shouldReturn: P) -> R {
        let h = heavy as! H
        h.callMe("Hello")
        print("Invoked")
        return "Hello" as! R
    }  
}

let heavy = Heavy<(Int, String), String>()
let delegate = Delegate()
heavy.delegate = delegate
heavy.inject((5, "alive"))

언급URL : https://stackoverflow.com/questions/24469913/how-to-create-generic-protocols-in-swift

반응형