通过“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 的测试方式,尤其不是值类型。你可以使用RawPointers,但实际上 - 你不应该。对于值类型,您永远不应该关心内存级别的对象相等性 - 您应该只关心属性是否相等。 我同意,我只是好奇在那个小例子中玩弄(并实际学习)写时复制行为 @MartinMlostek 在您的示例中没有写时复制行为。 Copy-on-write 是一种额外的优化,仅由某些内置类型(例如ArrayDictionary)实现。对于自定义类型,您需要自己实现它。默认情况下,值类型会在每个赋值上被复制,而不仅仅是在改变它们时。你不会改变structure,所以如果有写时复制,你的测试就会通过。 Copy-on-write 确实与结构无关。碰巧标准库中的所有 CoW 类型都是结构。这是一种手动实现的模式,可以很容易地在一个类上实现。在分配String 的情况下,绝对没有什么不寻常的事情发生。字符串是结构体,结构体被复制到新变量中。但是字符串结构只有 3 个机器字(IIRC)。所有实际的字符数据都存储在堆分配的缓冲区中。该缓冲区是在突变时复制的(如果没有其他拥有引用

以上是关于通过“identical to”灵活匹配结构的主要内容,如果未能解决你的问题,请参考以下文章

设计模式 - 结构型模式_桥接模式

C 结构中的灵活数组成员

如何用结构模式匹配表达 hasattr() 鸭子类型逻辑?

slot插槽(学习笔记)

MongoDB:数据模型介绍

Python 高级教程之结构化模式匹配