协议扩展中的嵌套结构:类型“...”不能嵌套在通用函数“...()”中

Nesting structs in Protocol Extension: Type '...' cannot be nested in generic function '...()'

我有一个协议,假设是 Fruit(见下文)。

在其中一种方法中,我想使用自定义结构。 这会导致以下错误:

Type 'Packet' cannot be nested in generic function '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)
    }
}

正在寻找解决方案或可行的替代方案。
我试过使用元组,但我需要将数据包保存到数据中,这使用元组不容易实现(据我所知)。

您不能以这种方式在扩展中的泛型结构中嵌套新类型。允许这样做可能会变得非常复杂,因为尚不清楚此类型是 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 包含对在这些地方定义的类型变量的引用,您应该首先考虑如何工作。 (我并不是说这些根本就是无法克服的问题,这可能是一个优秀的特性,也许可以设计得很好,你只需要考虑它如何与语言的其他特性交互即可。)

解决方案是将 Packet 移动到顶层,在扩展和协议之外。