如何在Rust中从另一个字符中减去一个字符?

时间:2019-02-07 22:38:16

标签: rust char

在Java中,我可以做到这一点。

canvas.move(rc1, x, y)
canvas.move(rc2, y, x)

我在Rust中尝试过相同的方法

x1, y1 = 5, 0
x2, y2 = -13, 7
canvas.move(rc1, x1, y1)
canvas.move(rc2, y2, x2)

但是编译器抱怨:

int diff = 'Z' - 'A'; // 25

如何在Rust中执行等效操作?

2 个答案:

答案 0 :(得分:7)

该操作在Unicode世界中是没有意义的,而在ASCII世界中却几乎没有意义,这就是为什么Rust不直接提供它的原因,但是有两种方法可以实现,具体取决于您的用例:

  • 将字符转换为标量值:'Z' as u32 - 'A' as u32
  • 使用字节字符文字:b'Z' - b'A'

答案 1 :(得分:0)

数学在 unicode 中并非毫无意义,它错过了 utf-8 最令人惊奇的功能。

任何高位为 0 的 7 位字符都是有效的 us-ascii,一个 7 位的 us-ascii doc 是有效的 utf-8。您可以将 utf-8 视为 us-ascii 字节,前提是所有比较和数学处理都处理低于 127 的值。 这是 utf-8 的设计,C 代码往往可以正常工作,但是 rust 使这变得复杂。

给定一个字符串 value: &str

抓取字节 as_bytes()

for byt in value.as_bytes() {
    let mut c = *byt; // c is u8 (unsigned byte)

    // if we are dealing with us-ascii chars...
    if c >= b'A' && c <= b'Z' {
        // math works, this converts to us-ascii lowercase
        c = c + 32;  
    }

    // to treat the u8 as a rust char cast it
    let ch = c as char;
    // now you can write sane code like  
    if ch == ':' || ch == ' ' || ch == '/' {
        ....
    // but you cant do math anymore

这个数学不是毫无意义的,+32 是一个方便的 A-Z 小写函数,这是对 utf-8 字符的有效处理。

utf-8 中的 a + 1 = b 并非偶然。 Ascii-beticaly 排序可能与现实世界的字母排序不同,但它仍然很有用,因为它在常见的字符范围内表现良好。

ascii 中的 '3' + 1 = '4' 并非毫无意义。

您不会将字符串 utf-8 分解为字节,即使字符串中有笑脸便便,像 if (c == 'a') 这样的简单代码也能工作。

对 Rust 的 char 进行数学运算是不可能的,这是一种耻辱。

对 utf-8 字符串的一个字节进行数学运算与以往一样有效。