为了消除堆分配的必要性,我们如何使用Span<T>
而不是string.Substring
?假设我们有以下代码:
var firstNameAndFamilyName="myname,myfamily";
var span = firstNameAndFamilyName.AsSpan().Slice(0,6);
var firstName = .... // How can I get 'myname' without allocating any new memory on the heap?
请注意,我知道字符串"myname,myfamily"
位于堆上,firstName
需要指向堆中的某个位置。 我的问题是,我们如何指向一个字符串子集,而又不将该部分对应到堆内存的新位置?
我知道已经向String类添加了一个新的构造函数,该构造函数接受ReadOnlySpan<T>
如下:
var firstName = new string(span);
但是我找不到任何地方是否通过在堆上分配来完成。
答案 0 :(得分:4)
众所周知,System.String
is immutable。不,但是,如果。如果您有Span<char>
,并且想将它们视为string
,则会分配新的内存。
好消息是,随着Span<>
的引入,除接受字符串和数组之外,该框架中的许多内置方法也进行了更新以接受。引用this MSDN article(我已经添加了一些示例的链接):
..已在整个框架中添加了许多此类方法。从
System.Random
到System.Text.StringBuilder
到System.Net.Sockets
,已经添加了重载功能,从而使{ReadOnly}Span<T>
和{ReadOnly}Memory<T>
的使用变得简单而高效。
这还包括所有数字{Try}Parse(string)
方法,现在将具有相应的(ReadOnlySpan<char>)
overloads。
var str = "123,456";
var span = str.AsSpan(0,3);
var i = int.Parse(span);
因此,不要让string
超出范围,而是看看您要实现的目标是否可以直接利用Span<>
。