Вложенные структуры в расширении протокола: тип '...' не может быть вложен в обобщенную функцию '... ()' - PullRequest
0 голосов
/ 07 марта 2019

У меня есть протокол, скажем, Fruit (см. Ниже).

В одном из методов я хочу использовать пользовательскую структуру.Это приводит к следующей ошибке:

Тип 'Пакет' не может быть вложен в универсальную функцию 'saveObject ()'

Почему это запрещено?

protocol Fruit: Codable
{
    var vitamines: Int { get }
    var description: String { get }
}

extension Fruit
{
    func saveObject()
    {
        struct Packet
        {
            let val1, val2, val3: Int
        }
        let packet = Packet(val1: vitamines, val2: 0, val3: 0)
    }
}

В поисках решения или жизнеспособных альтернатив.
Я пытался использовать кортеж, но мне нужно сохранить пакет в данные, что нелегко с помощью кортежа (насколько язнаю).

1 Ответ

1 голос
/ 07 марта 2019

Вы не можете таким образом вкладывать новые типы в общие структуры в расширениях. Разрешение этого, вероятно, станет очень сложным, так как не совсем ясно, будет ли этот тип Fruit.saveObject.Packet или <ConformingType>.saveObject.Packet. Например, рассмотрим следующий (допустимый) код, описывающий, как эти типы типов могут скрываться, и система должна иметь с ними дело, включая знание того, как отправлять им методы, сколько памяти им требуется и т. Д.

protocol P {}

func x() -> P {
    struct T: P {}
    return T()
}

type(of: x())

Если вы измените это, чтобы сделать x() универсальным, то это больше не будет законно:

func x<Y>() -> P {
    struct T: P {} // error: type 'T' cannot be nested in generic function 'x()'
    return T()
}

Тем не менее, если вы считаете, что язык должен быть изменен, чтобы позволить это, тогда Swift Evolution - это процесс, чтобы предложить это. Сначала вы должны подумать, как бы вы хотели, чтобы это работало, если Fruit имел ассоциированные типы, если saveObject() был сам по себе универсальным, и если Packet включал ссылку на переменную типа, определенную в любом из этих мест. (Я не говорю, что это непреодолимые проблемы вообще. Это может быть отличной особенностью, и может быть возможно очень хорошо спроектировать ее. Вам просто нужно продумать, как она взаимодействует с другими функциями языка.)

Решение состоит в том, чтобы переместить пакет на верхний уровень, вне расширения и вне протокола.

...