为未命名的默认参数传递通用结构会导致垃圾属性

Passing generic struct for unnamed default parameter results in garbage properties

我在不久前创建的 class 中看到一些奇怪的行为,结构的属性似乎在传递(复制)到方法后立即发生变化。

我已将其归结为一个简单的测试用例,可以在操场上 运行:

struct StructToPass<T> {
    let x: T
}

class MyClass<T> {
    func createAndPassStructWithValue(value: T) {
        let structToPass = StructToPass(x: value)
        println("Before passing to method: \(structToPass.x)")
        passStruct(structToPass)
    }

    func passStruct(_ theStruct: StructToPass<T>? = nil) {
        println("Inside method: \(theStruct!.x)")
    }
}

let myClass = MyClass<Int>()
myClass.createAndPassStructWithValue(42)

查看相关打印语句,可以看出struct的x 属性发生了变化:

// Before passing to method: 42
// Inside method: 140734543799888


在 class 之外创建结构并直接调用 passStruct(_:) 会导致 playground 崩溃,将 passStruct(_:) 编写为函数也是如此:

// Causes playground to crash:
let aStruct = StructToPass(x: 42)
myClass.passStruct(aStruct)

// Also causes playground to crash:
func passStruct<T>(_ theStruct: StructToPass<T>? = nil) {}
passStruct(aStruct)


passStruct(_:) method/function 更改为使用默认外部参数名称可解决此问题,引入另一个参数(before/after 默认参数)也是如此:

// This works:
func passStruct<T>(theStruct: StructToPass<T>? = nil) {
    println("Inside function: \(theStruct!.x)")
}
passStruct(theStruct: aStruct)

// This also works:
func passStruct<T>(_ theStruct: StructToPass<T>? = nil, someOtherParam: Int) {
    println("Inside function: \(theStruct!.x)")
}
passStruct(aStruct, 42)


这是编译器错误吗?当具有默认值的单个参数的泛型 function/method 不使用外部参数名称时,编译器似乎不喜欢它。这是一个具体案例,但我认为它应该有效。如果它不应该工作,应该有一个编译器警告。

110% 的编译器错误。我什至在 Playground 上试过这个。直到您想添加一行实际执行某些操作(例如发送 passStruct)之前,一切都会顺利进行编译。这有各种各样的问题。我什至失败了:

func passStruct<T>(_ theStruct: StructToPass<T>? = (nil as StructToPass<T>?)) {
    println("Inside function: \(theStruct!.x)")
}

我觉得这可能是问题所在(尽管不应该是我在其他地方遇到过的问题)。

找到了!报告它。他们显然还没有完成仿制药。在我的实验中,我发现通用 class 属性是不允许的。

static let nilStruct: StructToPass<T>? = nil

无法编译,出现 "not yet supported" 错误消息之一。