在 Microsoft.Extensions.Primitives 包lib中,有一个类StringSegment
,其注释表明它是:
子串的优化表示。
我没有意识到这个特定的类,直到我发现aspnet announcement #244,说明: Microsoft.Net.Http.Headers转换为使用StringSegments 。
但是,看看implementation of the StringSegment课程,我看不出它实际服务的目的是什么。我看到一个缓冲区,我想这可能表示对部分字符有更好的操作('段'部分可能?)。我还看到几个辅助函数,它们与常规字符串中已有的行为(如果不完全相同)密切相关,例如StartsWith / Endswith,Substring等。aspnet-core docs完全列出这些函数,但这也缺乏背景"为什么"它应该被使用。
那么StringSegment
类的目的究竟是什么?在哪种情况下它适用于它?
当我操作字符串时,在我的应用程序代码中调用类是否有用? 我们能有一个例子,它会有益吗?
答案 0 :(得分:7)
它允许您对另一个字符串的子字符串执行各种字符串操作,不使用实际调用Substring()
并创建新的字符串对象。它大致类似于C中的方式,你可以有一个指向字符串中间的指针:
char * s1 = "foo bar";
char * s2 = p + 4;
s2
"是"字符串" bar",在有用的意义上。
以示例StringSegment.IndexOf()
为例:您可以在字符串段中获取字符的索引,而无需先在较大的字符串上调用Substring()
并分配新的缓冲区:
public int IndexOf(char c, int start)
{
return IndexOf(c, start, Length - start);
}
你可以修剪" StringSegment
至"删除"空白也是:
public StringSegment TrimStart()
{
var trimmedStart = Offset;
while (trimmedStart < Offset + Length)
{
if (!char.IsWhiteSpace(Buffer, trimmedStart))
{
break;
}
trimmedStart++;
}
return new StringSegment(Buffer, trimmedStart, Offset + Length - trimmedStart);
}
这些是非常便宜的操作,没有分配等等。
你可以通过自己玩索引来完成所有这些工作,但这种代码很烦人且容易出错。你更喜欢在它周围包裹一个抽象。
它也是&#34;延期&#34;致电String.Substring()
。什么(希望)获得的是,如果你创建了许多这些,它们中的大多数或全部将永远不会返回实际的子串。
查看构造函数:
public StringSegment(string buffer, int offset, int length)
公共属性String Buffer
,int Offset
和int Length
都是只读的。
Value
属性:
public string Value
{
get
{
if (!HasValue)
{
return null;
}
else
{
return Buffer.Substring(Offset, Length);
}
}
}
因此,如果您想要公开一系列可能很大的&#34;子串&#34;那么您可以相对便宜地创建这些东西。在一些更大的字符串。如果没有人调用Value.get
,Substring
永远不会被调用。如果你有很多并且消费者只获得其中一个或两个的价值,那么你已经避免了对Substring()
的大量调用。
正如Servy所观察到的,如果你在同一个对象上拨打Value
两次,你就会两次调用Buffer.Substring(Offset, Length);
而不是一次。如果你还在避免其他20个电话,那很容易就是净收益。您可能想知道为什么他们没有从Buffer.Substring()
缓存返回值。我不知道由于实习是否有必要,或者在实践中发现这种优化是不值得的。
答案 1 :(得分:0)
解析文本时,可能会创建或复制许多新的字符串对象。理论上这个类有助于减少处理大型子串时使用的内存。其他语言也有类似的概念(参见C ++ 17中的std :: string_view)