Я пытаюсь сделать некоторую композицию протокола для использования в инъекции зависимостей, но у меня возникает проблема, которая, как я подозреваю, может не иметь решение, которое я бы хотел, но для которого я не вижу логической причины:Почему мой простой протокол можно использовать только в качестве общего ограничения?
protocol DM1 {
func sayHi() -> Void
}
protocol DM2 {
func sayHello() -> Void
}
protocol VM1 {
typealias T: DM1
var dm: T { get }
}
protocol VM2 {
typealias T: DM2
var dm: T { get }
}
protocol RT: VM1, VM2 {
}
class James {
let rt: RT
init(rt: RT) {
self.rt = rt
}
}
Приведенных выше результаты кода ошибки в «„RT“протокола может быть использован только в качестве общего ограничения, поскольку он имеет Я, или связанные с ними требования типа» на rt
переменный экземпляре и создание экземпляра параметра для James
. Я действительно не понимаю, почему я не могу использовать это общее требование в своем классе James
.
Я первоначально сделал что-то, как показано ниже:
protocol DM1 {
func sayHi() -> Void
}
protocol DM2 {
func sayHello() -> Void
}
protocol VM1 {
var dm: DM1 { get }
}
protocol VM2 {
var dm: DM2 { get }
}
protocol RT: VM1, VM2 {
}
struct Fred: DM1, DM2 {
func sayHi() {
println("hi")
}
func sayHello() {
println("hello")
}
}
struct Bob: RT {
let dm: Fred
}
class James {
let rt: RT
init(rt: RT) {
self.rt = rt
}
}
Но это не удается, потому что «Type„Bob“не соответствует протоколу„VM1“» (и VM2
), который я могу сортировать понять, так как мой протокол требует, чтобы переменная имела конкретный тип протокола, а не какой-то тип экземпляра, который соответствует этому протоколу. Таким образом, вышеупомянутая версия должна была быть способом обойти это.
Кто-нибудь есть решение для того, что я хочу сделать (быть в состоянии сделать бетонную-структуру, которая соответствует RT
, имея в качестве dm
собственности конкретной структуры, которая соответствует как к DM1
и DM2
)?
Спасибо за ответ, и ссылка была, безусловно, полезна. Однако, хотя я понимаю, что я не могу использовать свой протокол как тип, потому что он имеет «typealias», я до сих пор не понимаю, почему это должно быть так - в чем смысл этого ограничения? И видите ли вы какой-либо способ сделать то, что я хотел бы сделать (предположительно, не используя 'typealias')? – Rupert
См. Мой отредактированный ответ. Надеюсь, это поможет - различие является абстрактным, но все сводится к типу безопасности. –
Благодарим вас за подробное объяснение. Я вижу, как может возникнуть проблема с изменяемой переменной, которая является протоколом с требованиями 'typealias', потому что конкретный класс, который имеет это свойство, будет ожидать, что на нем будет установлен только один тип, когда объявление предложит нам установить его в любой экземпляр, соответствующий этому протоколу. Но для неизменяемого свойства я бы подумал, что это не проблема, потому что мы можем вернуть только тот конкретный экземпляр. Я просто предполагаю, что разрешить его для неизменных свойств будет слишком сложно. – Rupert