Вложенные типы внутри протокола

Внутри протоколов могут быть объявлены вложенные типы, например:

protocol Nested {

    class NameOfClass {
        var property: String { get set }
    }
}

Xcode говорит "Тип здесь не разрешен":

Тип «NameOfClass» не может быть вложен в протокол «Вложенный»

Я хочу создать протокол, который должен иметь вложенный тип. Это невозможно или я могу сделать это другим способом?


person LettersBa    schedule 06.08.2015    source источник


Ответы (3)


Протокол не может требовать вложенного типа, но может требовать ассоциированного типа, который соответствует другому протоколу. Реализация может использовать либо вложенный тип, либо псевдоним типа, чтобы выполнить это требование.

protocol Inner {
    var property: String { get set }
}
protocol Outer {
    associatedtype Nested: Inner
}

class MyClass: Outer {
    struct Nested: Inner {
        var property: String = ""
    }
}

struct NotNested: Inner {
    var property: String = ""
}
class MyOtherClass: Outer {
    typealias Nested = NotNested
}
person ughoavgfhw    schedule 06.08.2015
comment
Круто, но не понял одного! Что означает тип кода Nested = NotNested? - person LettersBa; 08.08.2015
comment
Он создает псевдоним типа для удовлетворения требований Outer. Теперь у NotNested есть новое имя, как если бы оно было вложено в MyOtherClass. Если Outer объявляет о каком-либо использовании Nested, компилятор, вероятно, может сделать вывод об этом. - person ughoavgfhw; 08.08.2015

В качестве альтернативы вы можете иметь свойства экземпляра/типа внутри протокола, которые соответствуют другому протоколу:

public protocol InnerProtocol {
    static var staticText: String {get}
    var text: String {get}
}

public protocol OuterProtocol {
    static var staticInner: InnerProtocol.Type {get}
    var inner: InnerProtocol {get}
}

public struct MyStruct: OuterProtocol {
    public static var staticInner: InnerProtocol.Type = Inner.self
    public var inner: InnerProtocol = Inner()

    private struct Inner: InnerProtocol {
        public static var staticText: String {
            return "inner static text"
        }
        public var text = "inner text"
    }
}

// for instance properties
let mystruct = MyStruct()
print(mystruct.inner.text)

// for type properties
let mystruct2: MyStruct.Type = MyStruct.self
print(mystruct2.staticInner.staticText)
person Stephenye    schedule 16.06.2017

Вот ваш код, но так, чтобы он работал:

protocol Nested {
    associatedtype NameOfClass: HasStringProperty

}
protocol HasStringProperty {
    var property: String { get set }
}

И вы можете использовать его так

class Test: Nested {
    class NameOfClass: HasStringProperty {
        var property: String = "Something"
    }
}

Надеюсь это поможет!

person Ky Leggiero    schedule 23.05.2017