Для быстрой разработки я сделал протоколы под названием 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()
}
Мои ожидания:
Поскольку у меня есть два набора сокетов, я бы хотел использовать переключать среду между макетом и реальным, что было бы очень удобно для разработки и отладки.
Но есть ошибка в вк что мешает мне выполнить.
Любая помощь будет оценена по достоинству.





Вы можете сделать что-то вроде этого:
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()
}
Не пытайтесь использовать общий протокол таким образом. Вы можете использовать обычный протокол или класс, чтобы получить наследование, или универсальный класс, если общая часть важна. Но протокол с универсальным ассоциированным типом сам по себе не является типом.
Дубликат stackoverflow.com/questions/55066079/… и многих других