You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

.NET Core 2.1中如何拼接ReadOnlySpan<char>实例?

如何拼接多个ReadOnlySpan实例?

嘿,这个问题戳中了ReadOnlySpan一个很实际的使用痛点——它在拆分、切片字符串的时候快得飞起,但拼接确实不像普通string那样顺手。毕竟Span本质是内存的只读视图,没法直接像字符串那样用"+"合并,不过咱们有几种靠谱的解决办法:

方法一:手动计算长度+内存复制(性能最优)

既然是内存视图,那直接操作内存最实在:先算出所有Span的总长度,分配一块刚好够的char数组,再把每个Span依次复制进去,最后转成string就行。代码示例:

var hello = "Hello".AsSpan();
var space = " ".AsSpan();
var world = "World".AsSpan();

// 先算好总长度,避免内存浪费
int totalLength = hello.Length + space.Length + world.Length;
char[] resultBuffer = new char[totalLength];
int currentPos = 0;

// 逐个复制每个Span到缓冲区
hello.CopyTo(resultBuffer.AsSpan(currentPos));
currentPos += hello.Length;
space.CopyTo(resultBuffer.AsSpan(currentPos));
currentPos += space.Length;
world.CopyTo(resultBuffer.AsSpan(currentPos));

// 从char数组生成最终字符串
string result = new string(resultBuffer);

这种方式全程只分配一次内存(就是那个char数组),性能拉满,特别适合对性能敏感的场景。

方法二:用StringBuilder简化代码(更灵活)

如果你觉得手动复制太繁琐,.NET Core 2.1及以上的StringBuilder已经支持直接Append ReadOnlySpan了,代码会简洁很多:

var hello = "Hello".AsSpan();
var space = " ".AsSpan();
var world = "World".AsSpan();

// 要是提前知道总长度,还可以给StringBuilder指定Capacity,避免内部扩容
StringBuilder sb = new StringBuilder(hello.Length + space.Length + world.Length);
sb.Append(hello);
sb.Append(space);
sb.Append(world);

string result = sb.ToString();

这个方法代码更清爽,适合Span数量较多或者场景比较灵活的情况,性能也不会差太多——毕竟底层也是做内存复制,提前指定Capacity还能避免额外的内存分配。

避坑提醒

  • 别想着直接用+号拼接Span,ReadOnlySpan没有重载+运算符,这么写编译直接报错。
  • 如果是超高频的拼接场景,优先选第一种方法,StringBuilder虽然方便,但内部还是有一定的封装开销(不过大部分场景下完全可以忽略)。

内容的提问来源于stack exchange,提问作者hazzik

火山引擎 最新活动