Swift 在协议中使用泛型
Swift using generic in protocol
为了快速开发,我制定了名为 Message
和 Socket
的协议。
接下来是一个真实的实现和一个模拟的实现。代码在这里:
// Procotols
protocol Message {
}
protocol Socket {
associatedtype T: Message
var messages: [T] { get }
}
// Real implementation
class RealMessage: Message {
}
class RealSocket: Socket {
private(set) var messages: [RealMessage] = []
}
// Mocks
class MockMessage: Message {
}
class MockSocket: Socket {
private(set) var messages: [MockMessage] = []
}
class VC {
// Error here: Protocol 'Socket' can only be used as a generic constraint because it has Self or associated type requirements
var socket: Socket = MockSocket()
// The only way I know to solve this is using the codes below:
// var socket: MockSocket = MockSocket()
}
我的期望:
因为我有两套套接字,我希望我可以在模拟和真实环境之间切换,这对于开发和调试来说非常好。
但是 VC 中有一个错误使我无法完成。
如有任何帮助,我们将不胜感激。
你可以这样做:
class VC <T: Socket>{
var socket: T
// Error here: Protocol 'Socket' can only be used as a generic constraint because it has Self or associated type requirements
init(with socket: T) {
self.socket = socket
}
// The only way I know to solve this is using the codes below:
// var socket: MockSocket = MockSocket()
}
let vc = VC(with: MockSocket())
let vc2 = VC(with: RealSocket())
您可以使用另一个字段来存储实际消息,并通过计算值符合协议。不需要关联类型。
protocol Socket {
var messages: [Message] { get }
}
// Real implementation
class RealSocket: Socket {
var messages:[Message]{
return realMessages
}
private var realMessages: [RealMessage] = []
}
// Mocks
class MockSocket: Socket {
var messages:[Message]{
return mockMessages
}
private var mockMessages: [MockMessage] = []
}
class VC {
var socket: Socket = MockSocket()
}
不要尝试以这种方式使用通用协议。您可以使用普通协议,或 class 以获得继承,或者如果通用部分很重要,则使用通用 class 。但是具有泛型关联类型的协议本身并不是一种类型。
为了快速开发,我制定了名为 Message
和 Socket
的协议。
接下来是一个真实的实现和一个模拟的实现。代码在这里:
// Procotols
protocol Message {
}
protocol Socket {
associatedtype T: Message
var messages: [T] { get }
}
// Real implementation
class RealMessage: Message {
}
class RealSocket: Socket {
private(set) var messages: [RealMessage] = []
}
// Mocks
class MockMessage: Message {
}
class MockSocket: Socket {
private(set) var messages: [MockMessage] = []
}
class VC {
// Error here: Protocol 'Socket' can only be used as a generic constraint because it has Self or associated type requirements
var socket: Socket = MockSocket()
// The only way I know to solve this is using the codes below:
// var socket: MockSocket = MockSocket()
}
我的期望:
因为我有两套套接字,我希望我可以在模拟和真实环境之间切换,这对于开发和调试来说非常好。
但是 VC 中有一个错误使我无法完成。
如有任何帮助,我们将不胜感激。
你可以这样做:
class VC <T: Socket>{
var socket: T
// Error here: Protocol 'Socket' can only be used as a generic constraint because it has Self or associated type requirements
init(with socket: T) {
self.socket = socket
}
// The only way I know to solve this is using the codes below:
// var socket: MockSocket = MockSocket()
}
let vc = VC(with: MockSocket())
let vc2 = VC(with: RealSocket())
您可以使用另一个字段来存储实际消息,并通过计算值符合协议。不需要关联类型。
protocol Socket {
var messages: [Message] { get }
}
// Real implementation
class RealSocket: Socket {
var messages:[Message]{
return realMessages
}
private var realMessages: [RealMessage] = []
}
// Mocks
class MockSocket: Socket {
var messages:[Message]{
return mockMessages
}
private var mockMessages: [MockMessage] = []
}
class VC {
var socket: Socket = MockSocket()
}
不要尝试以这种方式使用通用协议。您可以使用普通协议,或 class 以获得继承,或者如果通用部分很重要,则使用通用 class 。但是具有泛型关联类型的协议本身并不是一种类型。