Swift在协议中使用泛型

问题描述 投票:1回答:3

为了快速发展,我制定了称为MessageSocket的协议。

接下来是一个真正的实现和一个模拟的实现。代码在这里:

// 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()
}

我的期望:

由于我有两组套接字,我希望我可以在mock和real之间切换环境,这对于开发和调试来说非常好。

但VC中有一个错误阻止了我的成就。

任何帮助将不胜感激。

swift covariance
3个回答
0
投票

不要试图以这种方式使用通用协议。您可以使用普通协议或类来获取继承,如果通用部分很重要,则可以使用泛型类。但是具有通用关联类型的协议本身不是一种类型。


0
投票

你可以这样做:

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())

0
投票

您可以使用另一个字段来存储实际消息,并通过计算值符合协议。不需要相关类型。

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()

}
© www.soinside.com 2019 - 2024. All rights reserved.