小编Luk*_*odt的帖子

在Rust中,什么是“基本类型”?

在某个地方,我选择了“基本类型”(及其基本属性#[fundamental])一词,而现在我想了解更多有关它的信息。我隐约记得它是关于在某些情况下放宽一致性规则的。而且我认为引用类型就是这种基本类型。

不幸的是,在网上搜索并没有带给我很多。Rust参考没有提到它(据我所知)。我刚刚发现了一个有关创建元组基本类型引入该属性的RFC 的问题。但是,RFC有一个关于基本类型的段落:

  • 一种#[fundamental]类型Foo是在其中实施全面实施Foo是一项重大变化。如上所述,&并且&mut是基本的。将此属性应用于Box,使其Box 行为与相干性相同&&mut相对于相干性。

我觉得这句话很难理解,感觉到我需要对整个RFC有深入的了解才能了解基本类型的这一点。我希望有人可以用更简单的术语来解释基本类型(当然,不必过多简化)。这个问题也可以作为一条容易找到的知识。

为了理解基本类型,我想回答以下问题(除了主要的“它们什至是什么?”问题,当然):

  • 基本类型能比非基本类型做更多的事情吗?
  • 作为图书馆作者,我可以从某些类型上标记为#[fundamental]吗?
  • 核心语言或标准库中的哪些类型是基本的?

rust

29
推荐指数
1
解决办法
1979
查看次数

如何索引Rust中的String

我试图在Rust中索引一个字符串,但编译器抛出一个错误.我的代码(Project Euler problem 4,playground):

fn is_palindrome(num: u64) -> bool {
    let num_string = num.to_string();
    let num_length = num_string.len();

    for i in 0 .. num_length / 2 {
        if num_string[i] != num_string[(num_length - 1) - i] {
            return false;
        }
    }

    true
}
Run Code Online (Sandbox Code Playgroud)

错误:

error[E0277]: the trait bound `std::string::String: std::ops::Index<usize>` is not satisfied
 --> <anon>:7:12
  |
7 |         if num_string[i] != num_string[(num_length - 1) - i] {
  |            ^^^^^^^^^^^^^
  |
  = note: the type `std::string::String` cannot be indexed by …
Run Code Online (Sandbox Code Playgroud)

string indexing rust

27
推荐指数
4
解决办法
2万
查看次数

如何将数组传递给Rust中的函数并更改其内容?

我想将一个数组传递给一个函数并更改其中的内容.我怎么能这样做,这是我下面的代码,但当然它不起作用.

fn change_value(mut arr: &[i32]) {
    arr[1] = 10;
}

fn main() {
    let mut arr: [int; 4] = [1, 2, 3, 4];
    change_value(&arr);
    println!("this is {}", arr[1]);
}
Run Code Online (Sandbox Code Playgroud)

我收到错误:"无法分配给不可变的vec内容__CODE__".

我一直在寻找,但作为一个漂亮的新手Rust程序员,我找不到任何东西.另外,Rust对其语言进行了大量修改并没有帮助,因此很多方法都被弃用或删除了.

arrays rust

26
推荐指数
1
解决办法
2万
查看次数

当我删除边界检查时,为什么我的代码运行速度较慢?

我在Rust写了一个线性代数库.

我有一个函数来获取给定行和列的矩阵单元格的引用.此函数以一对断言开始,行和列在边界内:

#[inline(always)]
pub fn get(&self, row: usize, col: usize) -> &T {
    assert!(col < self.num_cols.as_nat());
    assert!(row < self.num_rows.as_nat());
    unsafe {
        self.get_unchecked(row, col)
    }
}
Run Code Online (Sandbox Code Playgroud)

在紧密的循环中,我认为跳过边界检查可能会更快,所以我提供了一个get_unchecked方法:

#[inline(always)]
pub unsafe fn get_unchecked(&self, row: usize, col: usize) -> &T {
    self.data.get_unchecked(self.row_col_index(row, col))
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,当我使用这些方法来实现矩阵乘法(通过行和列迭代器)时,我的基准测试显示,当我检查边界时它实际上快了大约33%.为什么会这样?

我在两台不同的计算机上试过这个,一台运行Linux,另一台运行OSX,两者都显示效果.

完整的代码在github上.相关文件是lib.rs.感兴趣的功能是:

  • get 在第68行
  • get_unchecked 在第81行
  • next 在第551行
  • mul 在第796行
  • matrix_mul (基准)在第1038行

请注意,我正在使用类型级数来参数化我的矩阵(通过虚拟标记类型也可以选择动态大小),因此基准测试将两个100x100矩阵相乘.

更新:

我已经大大简化了代码,删除了在基准测试中没有直接使用的东西并删除了泛型参数.我还编写了一个不使用迭代器的乘法实现,并且该版本不会产生相同的效果.有关此版本的代码,请参见此处.克隆minimal-performance分支并运行cargo bench将对两种不同的乘法实现进行基准测试(请注意,断言在该分支中以注释开头).

另外值得注意的是,如果我更改get*函数以返回数据的副本而不是引用(f64而不是&f64 …

optimization performance rust llvm-codegen

26
推荐指数
1
解决办法
740
查看次数

有没有办法让Rust将指针视为非别名,所以它可以将它们标记为LLVM优化器的"noalias"?

以下指针别名示例:

pub unsafe fn f(a: *mut i32, b: *mut i32, x: *const i32) {
  *a = *x;
  *b = *x;
}
Run Code Online (Sandbox Code Playgroud)

编译成以下程序集(with -C opt-level=s):

example::f:
        push    rbp
        mov     rbp, rsp
        mov     eax, dword ptr [rdx]
        mov     dword ptr [rdi], eax
        mov     eax, dword ptr [rdx]
        mov     dword ptr [rsi], eax
        pop     rbp
        ret
Run Code Online (Sandbox Code Playgroud)

请注意,x它被解除引用两次.LLVM没有将其视为noalias.我的第一个想法是避免在赋值中使用指针,而是使用安全引用(因为那些" 遵循LLVM的作用域noalias模型 ")来给优化器提示:

pub fn g(a: *mut i32, b: *mut i32, x: *const i32) {
  let safe_a = unsafe { …
Run Code Online (Sandbox Code Playgroud)

rust llvm-codegen

26
推荐指数
1
解决办法
417
查看次数

为什么需要绑定`T:'a`来存储引用`&'a T`?

鉴于此代码:

struct RefWrapper<'a, T> {
    r: &'a T,
}
Run Code Online (Sandbox Code Playgroud)

...编译器抱怨:

错误:参数类型T可能活不够长

考虑添加显式生命周期绑定,T: 'a以便引用类型&'a T不会超过它指向的数据.

我已经多次看过这个错误了,到目前为止我只是听了编译器,一切都很顺利.但是,考虑更多,我不明白为什么我要写T: 'a.

据我了解,已经不可能得到这样的参考.有&'a T暗示有类型的对象T是至少生存'a.但是我们不能在所述对象中存储任何引用,这些引用指向具有比生命周期短的数据'a.这已经导致编译错误.

在这个意义上它已经是不可能得到一个&'a T地方T不活得长'a.因此,附加注释(T: 'a)不应该是必需的.

我对吗?我错了,如果是的话:如果T: 'a不需要,我怎么能破坏代码呢?


链接:

lifetime rust

24
推荐指数
2
解决办法
437
查看次数

如何将Rust编译为机器代码?

我最近一直在研究Rust编程语言.它是如何工作的?Rust代码似乎被编译成ELF或PE(等)二进制文件,但我无法找到有关如何完成的任何信息?它被编译成中间格式,然后用gxx编译其余部分吗?任何帮助(或链接)将非常感激.

rust llvm-codegen

24
推荐指数
1
解决办法
4269
查看次数

什么优化级别`-Os`和`-Oz`在rustc中做什么?

执行rustc -C help节目(除其他外):

-C opt-level=val       -- optimize with possible levels 0-3, s, or z
Run Code Online (Sandbox Code Playgroud)

我认为级别0到3非常直观:级别越高,执行的优化程度越高.但是,我不知道这些sz选项正在做什么,我找不到与它相关的Rust相关信息.

rust llvm-codegen

23
推荐指数
2
解决办法
3337
查看次数

为什么我的可执行文件中的入口点地址是0x8048330(0x330是.text部分的偏移量)

我写了一个小程序添加到整数和使用"readelf -a executable_name"它显示了elf标题中的入口点地址:

Entry point address: 0x8048330
Run Code Online (Sandbox Code Playgroud)

我的可执行文件如何事先知道这个地址,甚至在加载器加载到内存之前?elf_format.pdf表示该成员提供系统首先转移控制的虚拟地址,从而启动该过程.任何人都可以解释这句话的含义是什么,这里虚拟地址的含义是什么?

另请告诉我,可执行文件的值为0x8048330,作为入口点地址.只是为了交叉检查我编译了另一个程序,为此,入口点地址保持相同的值0x8048330(两种情况下.text部分的偏移量为0x330).

c linux x86 assembly elf

19
推荐指数
3
解决办法
8968
查看次数

获取作为参数传入的数组的大小

我似乎无法做到这一点.我一直收到一个错误,说'len'在类型'&[str]'上不存在.

fn testLength(arr: &[String]) {
    if arr.len >= 10 {
        // Do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

我还是Rust的新手,我知道这是一个指向原始字符串的指针.为什么我不能在运行时获取底层字符串的长度?谷歌搜索"生锈中的绳子长度"和"生锈中的阵列长度"这些东西绝对没有让我感到满意.

arrays slice rust

19
推荐指数
1
解决办法
1万
查看次数

标签 统计

rust ×9

llvm-codegen ×4

arrays ×2

assembly ×1

c ×1

elf ×1

indexing ×1

lifetime ×1

linux ×1

optimization ×1

performance ×1

slice ×1

string ×1

x86 ×1