通过“identical to”灵活匹配结构
Posted
技术标签:
【中文标题】通过“identical to”灵活匹配结构【英文标题】:Nimble matching of struct via "identical to" 【发布时间】:2020-06-26 10:55:18 【问题描述】:我在单元测试期望映射中使用灵活,并且有一个关于比较结构的问题。
我观察到的是匹配的.to(be(x))
根本不适用于结构。所以下面的单元测试失败了:
func someTest()
struct Struct
let a: String
let b: String
let structure = Struct(a: "a", b: "b")
expect(structure).to(be(structure))
这是否意味着写入时复制机制在这里启动并且我们正在查看 2 个副本?为什么那个测试失败了?
【问题讨论】:
【参考方案1】:be()
函数实际上调用了beIdenticalTo
,它使用指针相等检查,所以它只适用于引用类型。请参阅BeIdenticalTo source code。
您应该使Struct
符合Equatable
并改用equal
。
func someTest()
struct Struct: Equatable
let a: String
let b: String
let structure = Struct(a: "a", b: "b")
expect(structure).to(equal(structure))
【讨论】:
啊,nimble是否可以实际比较指针指向的地址? @MartinMlostek 这不是 Swift 的测试方式,尤其不是值类型。你可以使用RawPointer
s,但实际上 - 你不应该。对于值类型,您永远不应该关心内存级别的对象相等性 - 您应该只关心属性是否相等。
我同意,我只是好奇在那个小例子中玩弄(并实际学习)写时复制行为
@MartinMlostek 在您的示例中没有写时复制行为。 Copy-on-write 是一种额外的优化,仅由某些内置类型(例如Array
和Dictionary
)实现。对于自定义类型,您需要自己实现它。默认情况下,值类型会在每个赋值上被复制,而不仅仅是在改变它们时。你不会改变structure
,所以如果有写时复制,你的测试就会通过。
Copy-on-write 确实与结构无关。碰巧标准库中的所有 CoW 类型都是结构。这是一种手动实现的模式,可以很容易地在一个类上实现。在分配String
的情况下,绝对没有什么不寻常的事情发生。字符串是结构体,结构体被复制到新变量中。但是字符串结构只有 3 个机器字(IIRC)。所有实际的字符数据都存储在堆分配的缓冲区中。该缓冲区是在突变时复制的(如果没有其他拥有引用以上是关于通过“identical to”灵活匹配结构的主要内容,如果未能解决你的问题,请参考以下文章