【问题标题】:Applying string manipulation to a variable without setting the variable = to the result? [duplicate]将字符串操作应用于变量而不将变量 = 设置为结果? [复制]
【发布时间】:2017-07-20 18:17:17
【问题描述】:

这可能以前有人问过,但我找不到。我认为我的 googlefu 不够好。总之,

说我有这个:

string cat = "meow"
cat = cat.replace("meow","purr");
cat = Regex.Replace(cat, "purr", "Meow!");

将 cat 变量设置为它的操纵副本似乎是额外的。有没有办法通过 ref 方式执行此操作,这样我就不必将变量设置为自身的修改版本?

要明确的是,我在这里询问的是上面的第 2 行和第 3 行。

编辑:我不相信marked dupe 是对我问题的完全欺骗。我的问题是专门针对这种事物存在的询问。链接的帖子专门解释了为什么它不存在。对于不熟悉不可变概念的人来说,这个问题可能仍然值得保留。

【问题讨论】:

  • 您可以直接使用cat = cat.replace("meow", "Meow!")。我认为这个例子不是一个好例子。你的意思是问如何在不创建临时变量的情况下交换两个字符串?
  • @WiktorStribiżew 仅提供您将变量设置为自身的多种情况。上面的代码没有最终的游戏目标。 :P

标签: c# regex string variables


【解决方案1】:

在 C# 中,字符串是不可变的。这意味着您不能安全地更改变量引用的字符串值。即没有看起来像这样的方法:

string cat = "meow";
cat.replace("meow", "purr");
Console.WriteLine(cat); // expected "purr", but output is still "meow"

您可以为每个要改变变量的字符串操作编写包装器方法,例如:

void replace(ref string value, string regex, string replaceString) {
    value = value.replace(regex, replaceString);
}

然后像这样使用它:

replace(cat, "meow", "purr");

但是,不要那样做。它很混乱且无法维护。为您可能想要执行的每个字符串操作编写方法,只是为了实现字符串可变性的错觉,这不是好的做法。

您可以尝试改用StringBuilder,如下所示:

string cat = "meow";
StringBuilder stringBuilder = new StringBuilder(cat);
stringBuilder.Replace("meow", "purr");
Console.WriteLine(stringBuilder.ToString());

【讨论】:

  • 强调不可变
  • 完美答案谢谢。完美的解释,现在我知道什么是不可变了!
  • 这并不完全正确,因为字符串可以以不安全的方式进行修改:stackoverflow.com/questions/32464944/…
  • 我对帖子进行了小幅编辑,以包含“安全”。幸运的是,这篇文章被标记为重复,因此可以得到更详细解释的答案。
【解决方案2】:

来自文档:

因为字符串是不可变的,所以不可能(不使用 不安全代码)来修改字符串对象的值 创建的。但是,有很多方法可以修改字符串的值 并将结果存储在一个新的字符串对象中。

你可以做的是使用 StringBuilder 类:

StringBuilder builder = new StringBuilder();
builder.Append("Juan");
builder.Replace("Juan", "Javier");
Console.WriteLine(builder.ToString()); //This outputs "Javier"

StringBuilder 还允许您使用索引在字符级别修改字符串:

builder[0] = 'X';
Console.WriteLine(builder.ToString()); //This outputs "Xavier"

【讨论】:

  • 嗯,字符串生成器有什么缺点吗?为什么要使用string 而不是StringBuilder
  • @CapnJack:不同之处正是您想要的。 StringBuilder 存在于您不想创建新实例的这种情况。因为 StringBuilder 维护一个字符的内部缓冲区,它允许您在不创建新实例的情况下进行更改。
  • @CapnJack:这对于少量操作可能不是问题,但是当性能至关重要并且您拥有数百万个操作时,您可以使用缓冲区(您可以将其初始化为已知大小,由方式)变得非常有用且性能更高。
  • 这很有意义。在不同线程上阅读相同的字符串也有助于突出差异。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多