为未命名的默认参数传递通用结构会导致垃圾属性
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" 错误消息之一。
我在不久前创建的 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" 错误消息之一。