为什么将第一个字符串的第一个字母大写,以便在RUTR中卷积?

2021-06-10 03:51:20

我喜欢利用A& str的第一个字母。它'我是一个简单的问题,我希望一个简单的解决方案。直觉告诉我做这样的事情:

但& strs可以' t索引。我能够做到的唯一方法似乎过分搞砸了。我将& str转换为迭代器,将迭代器转换为向量,大写向量中的第一个项目,它创建一个迭代器,我索引它,创建一个选项,我打开了一个ock,给我一个上套第一个字母。然后我将向量转换为迭代器,我转换为一个字符串,我转换为a& str。

让S1 =" foobar&#34 ;;让mut v:vec< char> = s1.chars()。收集(); v [0] = v [0] .to_uppercase()。第n(0).unwrap(); let s2:string = v.into_iter()。收集();让S3 =& S2;

有什么比这更容易的方式,如果是的话,是什么?如果没有,为什么RUDE这样的方式?

5' s一个简单的问题 - 没有,它'没有。请在被解释为德语时大写ß提示:它' s不是一个字符。即使是问题陈述也可能是复杂的。例如,利用姓氏Von Hagen的第一个性格是不当的。这是生活在一个全球性世界中的一个方面,这些世界已经有数千年的不同实践,我们正试图将所有人挤进到8位和2行代码中。 - Shepmaster.

你姿势似乎是一个字符编码问题,而不是数据类型问题。我假设char :: to_uppercase已经正确处理Unicode。我的问题是,为什么需要所有数据类型转换?它似乎索引可以返回一个多字节,Unicode字符(不是单个字节字符,它只假设ASCII),并且To_Uppercase可以以任何语言返回一个大写字符,如果可以在说明的情况下语。 - Marshallm.

@marshallm char :: to_uppercase确实处理了这个问题,但你只拍摄了第一个代码点(第n(0))而不是构成大写的所有代码点 - User395760.

字符编码不是一个直接的过程,如joel在软件上指出:Unicode。 - 内森

@shepmaster,一般来说你是正确的。它'是一种简单的英语问题(关于编程语言和数据格式的事实上的标准基础)。是的,有脚本在其中"资本化"甚至不是一个概念,其他人在那里是非常复杂的。 - Paul Draper.

我们创建了一个在UTF-8中编码的文字字符串。 UTF-8允许我们以' s漂亮紧凑的方式编码1,114,112个代码点,如果您来自世界各种角色,在ASCII中的主要特征,在1963年创建的标准。UTF-8是一个可变长度编码,这意味着单个代码点可能需要1到4个字节。较短的编码是为ASCII保留的,但许多Kanji在UTF-8中占用3个字节。

这创建了字符的矢量。字符是32位数字,直接映射到代码点。如果我们开始使用ASCII的文本,我们' VE四倍的内存要求。如果我们从星期形飞机上有一堆角色,那么也许我们没有更多地使用。

这抓住了第一代码点和请求它将其转换为大写变体。不幸的是,对于那些长大的英语,那里的人来说,并不总是一个简单的一对一映射A"小字母"到A"大字母"侧面注意:我们称之为大写和小写,因为一箱字母在一天的另一盒子上方。

当代码点没有相应的大写变体时,此代码将恐慌。我不确定那些是否存在。当代码点具有具有多个字符的大写变体时,它也可以在语义上失败,例如德国ß。请注意,ß可能永远不会在现实世界中大写,这是我可以永远记住和搜索的例子。截至2017-06-29,实际上,德国拼写的官方规则已经更新,以便兼第#34;ß"和#34; ss"是有效的资本化!

在这里,我们将字符转换回UTF-8,并且需要新的分配来存储它们,因为原始变量存储在恒定存储器中,以便在运行时不会占用内存。

不幸的是,这不是真的。也许我们应该努力将世界转化为esperanto?

是的,我当然希望如此。不幸的是,Unicode ISN' t在所有情况下都足够了。感谢Huon指出土耳其语I,其中Unipe(İ)和小写(i)版本都有一个点。也就是说,没有一个正确的字母I;它也取决于源文本的区域设置。

因为您担心正确性和性能时,您正在使用的数据类型很重要。 char是32位,符号为UTF-8编码。他们是不同的东西。

如果您完成字节字节,则可以切割字符串,但如果您不在字符边界,则标准库将恐慌。

索引字符串以获得角色的原因之一是从未实现的是因为这么多人滥用字符串作为ASCII字符数组。索引一个字符串来设置字符永远不会有效 - 你必须能够用一个值替换1-4个字节,这也是1-4个字节的值,导致其余的字符串围绕相当多的弹跳。

fn some_kind_of_uppercase_first_letter(s:& str) - > string {让mut c = s.chars();匹配c.next(){none => string :: new(),一些(f)=> f.to_uppercase()。链(c).collect(),}} fn main(){println!(" {}" some_kind_of_uppercase_first_letter(" joe")); println!(" {}}" some_kind_of_uppercase_first_letter(" jill")); println!(" {}" some_kind_of_uppercase_first_letter(" von hagen")); println!(" {}}",some_kind_of_uppercase_first_letter("ß"));}

但是我可能会在箱子上搜索大写或unicode.io,让别人比我更聪明地处理它。

谈到"有人比我更聪明",veedrac指出它'访问第一个大写代码点后,将迭代器转换回切片&#39。这允许其余的字节的麦现。

fn some_kind_of_uppercase_first_letter(s:& str) - > string {让mut c = s.chars();匹配c.next(){none => string :: new(),一些(f)=> f.to_uppercase()。收集::< string>()+ c.as_str(),}}

12思考很多后,我了解这些设计的选择更好。标准库应选择最通用,性能和安全的权衡。否则,它迫使开发人员进行权衡,可能不适合其应用程序,体系结构或区域设置。或者它可能导致歧义和误解。如果我更喜欢其他权衡,我可以选择第三方图书馆或自己写它。 - Marshallm.

@Marshallm那个&#39非常高兴!我担心许多新人来误解了生锈设计师所做的决定并简单地将它们写在太复杂,因为没有任何好处。通过在这里询问和回答问题,我欣赏了需要进入这样的设计,并希望成为更好的程序员。保持开放的心态并愿意学到更多内容是一个作为程序员的伟大特质。 - Shepmaster.

"土耳其I"是语言环境依赖的一个例子,它与比排序更直接相关。 - 欢呼

我惊讶的是他们有to_uppercase和to_lowercase但不是to_titlecase。 IIRC,一些Unicode字符实际上具有特殊的标题组变量。 - 蒂姆

顺便说一下,即使是单个代码点也可能不是正确的单位转换。如果第一个字符是一个图形集群,应该在上外壳时接受特殊处理的标记簇? (恰巧,分解变音工作,如果你只是大写的基本字符,但我不'知道如果这是普遍如此) - 塞巴斯蒂安雷尔

有什么比这更容易的方式,如果是的话,是什么?如果没有,为什么RUDE这样的方式?

好吧,是的,没有。你的代码是,正如其他答案所指出的那样,不正确,如果你给它像བོད་བོད་ལ་一样恐慌。所以用生锈和#39的标准图书馆这样做比你最初想到的更难。

但是,Fort旨在鼓励代码重用并使图书馆轻松。因此,用惯性方式来利用字符串实际上非常适合:

2用户的问题听起来更像是我想要的.to_sentence_case()。 - Christopher Oezbek.

可悲的是,它并不是讨论命名的东西......这是令人敬畏的图书馆,我以前从未见过它,但它' S名称很难(对我来说)记住,并且有几乎没有任何事情的职能实际的拐点,其中一个是你的例子。 - Sahsahae.

如果您能够将输入限制为仅限ASCII字符串,它并不特别是复杂的。

由于生锈1.23,str具有make_asci_uppercase方法(在旧的锈版版本中,通过ASCIIEXT特征可用)。这意味着您可以通过相对容易的方式大写ASCII的字符串切片:

1帮助rust newbie出来,为什么r变形?我看到s是一个可变的str。 OHHHH OK:我有答案我自己的问题:get_mut(这里调用w / a范围)显式返回选项<& mut&gt ;. - Steven Lu.

这就是我解决了这个问题的方式,注意我必须检查自己是否没有ASCII,然后在转换为大写之前。

特质标题{fn标题(& self) - >字符串;}} islich titlecase for& str {fn标题(& self) - >字符串{if!self.is_ascii()|| self.is_empty(){return string :: from(* self);让(头,尾巴)= self.split_at(1); head.to_uppercase()+ tail}} pub fn main(){println!(" {}}" bruno" .title()); println!(" {}}}" b" .title()); println!(" {}}""🦀" .title()); println!(" {}""ß" .title()); Println!(" {}}""" .title()); println!(" {}}""བོད་སྐད་ལ" .title());}

1

这里的一个版本比@ shepmaster' s的改进版本,但也更加惯用:

FN Capitalize_First(S:& str) - > string {让mut chars = s.chars();字符.next().map(| first_letter | first_letter.to_uppercase()).into_iter().flatten().chain(chars).collect()}

0.

点击“发布答案”,您同意我们的服务条款,隐私政策和Cookie政策 不是答案你和#39;寻找? 浏览其他标记的问题或提出您自己的问题。