gpt4 book ai didi

language-agnostic - 不可变集合上的非变异 "add"方法的最佳名称是什么?

转载 作者:行者123 更新时间:2023-12-03 04:07:43 25 4
gpt4 key购买 nike

对不起,标题太乱了——如果我能想出一个简洁的标题,我就不必问这个问题了。

假设我有一个不可变的列表类型。它有一个操作 Foo(x)它返回一个新的不可变列表,其中包含指定的参数作为末尾的额外元素。因此,要构建具有值“Hello”、“immutable”、“world”的字符串列表,您可以编写:

var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");

(这是 C# 代码,如果您认为该语言很重要,我对 C# 建议最感兴趣。这根本不是一个语言问题,但该语言的习语可能很重要。)

重要的是现有列表不会被 Foo 改变。 - 所以 empty.Count仍然会返回 0。

获得最终结果的另一种(更惯用的)方法是:

var list = new ImmutableList<string>().Foo("Hello")
.Foo("immutable")
.Foo("word");

我的问题是: Foo 最好的名字是什么?

编辑 3 :正如我稍后透露的那样,类型的名称实际上可能不是 ImmutableList<T> ,这使得位置明确。想象一下,它是 TestSuite并且它是不可变的,因为它所属的整个框架都是不可变的......

(编辑 3 结束)

到目前为止我想出的选项:
  • Add : 在.NET 中很常见,但意味着原始列表的变异
  • Cons : 我相信这是函数式语言中的正常名称,但对于没有此类语言经验的人来说毫无意义
  • Plus : 到目前为止我最喜欢的,它对我来说并不意味着突变。显然这也是used in Haskell但期望略有不同(Haskell 程序员可能希望它将两个列表添加在一起,而不是向另一个列表添加单个值)。
  • With :与其他一些不可变约定一致,但与 IMO 没有完全相同的“附加性”。
  • And : 不太好描述。
  • + 的运算符重载:我真的不太喜欢这个;我通常认为运算符应该只应用于较低级别的类型。不过我愿意被说服!

  • 我用于选择的标准是:
  • 给出方法调用结果的正确印象(即它是带有额外元素的原始列表)
  • 尽可能清楚地表明它不会改变现有列表
  • 像上面的第二个例子一样链接在一起时听起来很合理

  • 如果我说得不够清楚,请询问更多详细信息...

    编辑 1:这是我偏爱 Plus 的理由至 Add .考虑这两行代码:

    list.Add(foo);
    list.Plus(foo);

    在我看来(这是个人的事情)后者显然有问题——就像写“x + 5;”一样。作为自己的声明。第一行看起来没问题,直到你记得它是不可变的。事实上,加号运算符本身不会改变其操作数的方式是 Plus 的另一个原因。是我的最爱。没有运算符重载的轻微不适,它仍然给出了相同的含义,其中包括(对我而言)不改变操作数(或在这种情况下的方法目标)。

    编辑 2:不喜欢添加的原因。

    各种答案都是有效的:“使用 Add。这就是 DateTime 所做的,而 String 具有 Replace 方法等,这些方法不会使不变性变得明显。”我同意 - 这里有优先权。但是,我看到很多人拨打 DateTime.AddString.Replace并期待突变。有大量新闻组问题(如果我仔细研究的话,可能还有一些问题)的回答是“您忽略了 String.Replace 的返回值;字符串是不可变的,会返回一个新字符串。”

    现在,我应该揭示这个问题的微妙之处——类型实际上可能不是一个不可变的列表,而是一个不同的不可变类型。特别是,我正在研究一个基准测试框架,您可以在其中向套件添加测试,然后创建一个新套件。很明显:

    var list = new ImmutableList<string>();
    list.Add("foo");

    不会完成任何事情,但是当您将其更改为:

    var suite = new TestSuite<string, int>();
    suite.Add(x => x.Length);

    看起来应该没问题。而对我来说,这使错误更加清晰:

    var suite = new TestSuite<string, int>();
    suite.Plus(x => x.Length);

    那只是乞求:

    var suite = new TestSuite<string, int>().Plus(x => x.Length);

    理想情况下,我希望我的用户不必被告知测试套件是不可变的。我想让他们掉进成功的坑里。这可能是不可能的,但我想尝试一下。

    我很抱歉通过仅谈论不可变列表类型来过度简化原始问题。并非所有系列都像 ImmutableList<T> 一样具有自我描述性:)

    最佳答案

    在这种情况下,我通常会选择 Concat .这对我来说通常意味着正在创建一个新对象。

    var p = listA.Concat(listB);
    var k = listA.Concat(item);

    关于language-agnostic - 不可变集合上的非变异 "add"方法的最佳名称是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/521893/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com