Swift с использованием универсального в протоколе - PullRequest
1 голос
/ 15 марта 2019

Для быстрого развития я создал протоколы, называемые 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 , которая останавливает меня от выполнения.

Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

0 голосов
/ 15 марта 2019

Вы можете использовать другое поле для хранения фактических сообщений и соответствовать протоколу через вычисленное значение. Связанный тип не требуется.

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

}
0 голосов
/ 15 марта 2019

Не пытайтесь использовать общий протокол таким образом.Вы можете использовать обычный протокол, или класс, чтобы получить наследование, или универсальный класс, если универсальная часть важна.Но протокол с общим ассоциированным типом сам по себе не является типом.

0 голосов
/ 15 марта 2019

Вы можете сделать что-то вроде этого:

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