반응형
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
반응형
'programing' 카테고리의 다른 글
TSLint 오류 "최대 줄 길이 120을 초과함" (0) | 2023.08.19 |
---|---|
독립 실행형 응용 프로그램에서 스프링 사용 (0) | 2023.08.14 |
Android Studio Gradle 이미 폐기된 모듈 (0) | 2023.08.14 |
크롬: 배경 탭에서 시간 초과/간격이 일시 중단됩니까? (0) | 2023.08.14 |
활성 자녀의 부모를 위한 복합 CSS 선택기 (0) | 2023.08.14 |