gpt4 book ai didi

Swift:为符合通用协议(protocol)的通用类创建包装类时出错

转载 作者:行者123 更新时间:2023-11-28 11:30:45 24 4
gpt4 key购买 nike

我想为符合通用协议(protocol)的通用类创建一个包装器类,但由于某些原因我无法使其正常工作。

背后的想法是在应用程序中使用包装器 AnyNetworkRequest 作为 Erased-Type,这样就不需要像 _NetworkRequest 那样定义通用类型。

我看不到 AnyNetworkRequest 上有什么遗漏/错误。如果有人能指出我遗漏或错误的地方,我将不胜感激。

// Protocol with associatedtypes

public protocol NetworkRequest {

associatedtype RequestSerializationType: RequestSerializationProtocol
associatedtype RequestResponseType: NetworkResponseProtocol

var requestSerializer: RequestSerializationType { get }
var requestResponse: RequestResponseType? { get }
}


// Generic Request

public class _NetworkRequest<RequestSerializationType: RequestSerializationProtocol, RequestResponseType: NetworkResponseProtocol>: NetworkRequest {

fileprivate init() {}

public lazy var requestSerializer: RequestSerializationType = { RequestSerializationType.init() }()
public var requestResponse: RequestResponseType?
}

// Concrete Request

public class DataNetworkRequest: _NetworkRequest<ConcreteHTTPRequestSerializer, ConcreteDataNetworkResponse> {}

// Concrete Request

public class JSONDataNetworkRequest: _NetworkRequest<ConcreteJSONRequestSerializer, ConcreteJSONDataNetworkResponse> {}


// Type Erased Wrapper
// Cannot make this wrapper work
// Error 1: Type 'AnyNetworkRequest' does not conform to protocol 'NetworkRequest'
// Error 2: Reference to invalid associated type 'RequestSerializationType' of type 'AnyNetworkRequest'

public class AnyNetworkRequest : NetworkRequest { //E1

private let request : _NetworkRequest<RequestSerializationType, RequestResponseType> //E2

init<T: NetworkRequest>(_ networkRequest: T) where T.RequestSerializationType == RequestSerializationType, T.RequestResponseType == RequestResponseType {
request = networkRequest
}
}

编辑:第一次修改

// Protocol with associatedtypes

public protocol NetworkRequest {

associatedtype RequestSerializationType: RequestSerializationProtocol
associatedtype RequestResponseType: NetworkResponseProtocol

var requestSerializer: RequestSerializationType { get }
var requestResponse: RequestResponseType? { get }
}


// Generic Request

public class _NetworkRequest<RST: RequestSerializationProtocol, RRT: NetworkResponseProtocol>: NetworkRequest {

public typealias RequestSerializationType = RST
public typealias RequestResponseType = RRT


fileprivate init() {}

public lazy var requestSerializer: RequestSerializationType = { RequestSerializationType.init() }()
public var requestResponse: RequestResponseType?
}

// Concrete Request

public class DataNetworkRequest: _NetworkRequest<ConcreteHTTPRequestSerializer, ConcreteDataNetworkResponse> {}

// Concrete Request

public class JSONDataNetworkRequest: _NetworkRequest<ConcreteJSONRequestSerializer, ConcreteJSONDataNetworkResponse> {}


// Type Erased Wrapper
// Cannot make this wrapper work
// Error 1: Type 'AnyNetworkRequest' does not conform to protocol 'NetworkRequest'
// Error 2: Reference to invalid associated type 'RequestSerializationType' of type 'AnyNetworkRequest'

public class AnyNetworkRequest : NetworkRequest { //E1

/* // E1 forces me to include typealiases
public typealias RequestSerializationType = <#type#>
public typealias RequestResponseType = <#type#>
*/

private let request : _NetworkRequest<RequestSerializationType, RequestResponseType>

var requestSerializer: RequestSerializationType { //E2
return request.requestSerializer
}

var requestResponse: RequestResponseType? {
return request.requestResponse
}

init<T: NetworkRequest>(_ networkRequest: T) where T.RST == RequestSerializationType, T.RRT == RequestResponseType {
request = networkRequest
}
}

最佳答案

错误很容易解释。

1) 您的AnyNetworkRequest 类确实不符合NetworkRequest 协议(protocol)。顺便说一句,我不明白为什么它应该这样做。未满足的要求是 requestSerializerrequestResponse 属性以及所需的类型别名。通常,您可以将其重写如下:

public class AnyNetworkRequest: NetworkRequest {

var requestSerializer: RequestSerializationType {
return request.requestSerializer
}

var requestResponse: RequestResponseType? {
return request.requestResponse
}

private let request : _NetworkRequest<RequestSerializationType, RequestResponseType>

// ...
}

但它需要我们去

2) 需要为关联类型指定内容的地方。您不能在泛型声明中使用 RequestSerializationTypeRequestResponseType,因为它们不是具体类型。

所以你不能以这种方式执行类型删除。

除了输入更少的字母之外,我不知道为什么你需要在这里摆脱泛型,但我可以提供的是使用类型别名,比如:

typealias DataNetworkRequest = _NetworkRequest<ConcreteHTTPRequestSerializer, ConcreteDataNetworkResponse>

typealias JSONDataNetworkRequest = _NetworkRequest<ConcreteJSONRequestSerializer, ConcreteJSONDataNetworkResponse>

这样您就可以避免冗余继承并拥有更清晰表达的类型,以防这是您的目标。

AnyNetworkRequest 在这种情况下根本不需要。

关于Swift:为符合通用协议(protocol)的通用类创建包装类时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56788978/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com