It should be so much easier

I'm an old programmer, but I keep updated.
I several years I've already programmed in Cobol, C, SuperMumps, Clipper, Basic, Pascal, Linux Bash, PHP, Zim, MySql database, Firebird database, SuperMumps, Clipper, Basic, Delphi, Oracle, Python, Golang
I made a lot of softwares in all this years - utilities, stock exchange analytics, complete business softwares.

Recent Languages:

Python - I love - I miss an easy and fast compiler, but I've made a lot of softwares.

GoLang - Excelent ! I've made a lot of softwares.

Rust - I loved the packages and the Speed to compile and run. It seems also secure in terms of memory use, etc

I made a GUI software in Rust with fltk and it works, but I'm thinking in abandon Rust, because it's the most difficult language I already used. (syntax)
The learning curve it's the worst I've seen.

I'm taking 40 times more times to get the my code working than another languages.
I got in crates.io, get recent packages, copy the sample source code and a lot of source code does NOT work!!!
(http curl and a lot of another codes)

I never see so many errors in another languages I've used.
Rust have a good future, but needs to improve the documentation and create easier ways to write code (easier syntax)

Let's see all the errors that I have now in my Rust software:

error[E0015]: cannot call non-const fn `<sysinfo::System as SystemExt>::disks` in constants
   --> rustprg1.rs:463:28
    |
463 |     let mut discos: [str; sys.disks().len()] = [0; sys.disks().len()];
    |                               ^^^^^^^
    |
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const fn `<sysinfo::System as SystemExt>::new_all` in constants
   --> rustprg1.rs:455:31
    |
455 |     const sys: sysinfo::System = System::new_all();
    |                                  ^^^^^^^^^^^^^^^^^
    |
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0493]: destructor of `sysinfo::System` cannot be evaluated at compile-time
   --> rustprg1.rs:463:24
    |
463 |     let mut discos: [str; sys.disks().len()] = [0; sys.disks().len()];
    |                           ^^^             - value is dropped here
    |                           |
    |                           the destructor for this type cannot be evaluated in constants

error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> rustprg1.rs:463:18
    |
463 |     let mut discos: [str; sys.disks().len()] = [0; sys.disks().len()];
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
    = note: slice and array elements must have `Sized` type

error[E0015]: cannot call non-const fn `<sysinfo::System as SystemExt>::disks` in constants
   --> rustprg1.rs:463:53
    |
463 |     let mut discos: [str; sys.disks().len()] = [0; sys.disks().len()];
    |                                                        ^^^^^^^
    |
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0493]: destructor of `sysinfo::System` cannot be evaluated at compile-time
   --> rustprg1.rs:463:49
    |
463 |     let mut discos: [str; sys.disks().len()] = [0; sys.disks().len()];
    |                                                    ^^^             - value is dropped here
    |                                                    |
    |                                                    the destructor for this type cannot be evaluated in constants

error[E0308]: mismatched types
   --> rustprg1.rs:463:46
    |
463 |     let mut discos: [str; sys.disks().len()] = [0; sys.disks().len()];
    |                                                 ^ expected `str`, found integer

error[E0277]: the trait bound `str: std::marker::Copy` is not satisfied
   --> rustprg1.rs:463:46
    |
463 |     let mut discos: [str; sys.disks().len()] = [0; sys.disks().len()];
    |                                                 ^ the trait `std::marker::Copy` is not implemented for `str`
    |
    = note: the `Copy` trait is required because this value will be copied for each element of the array

error[E0425]: cannot find function `len` in this scope
   --> rustprg1.rs:464:16
    |
464 |     println!("{}",len(discos));
    |                   ^^^ not found in this scope

Some errors have detailed explanations: E0015, E0277, E0308, E0425, E0493.
For more information about an error, try `rustc --explain E0015`.
error: could not compile (rustprg1.rs") due to 9 previous errors

Another pieces of code that I'm having problem:

let name="John"+" Doe";
	let nromac="";
	for (interface_name, network) in networks {
		if  network.mac_address().to_string() != "00:00:00:00:00:00" && network.mac_address().to_string() != "" {
			let nromac=network.mac_address().to_string();		
			let mut nromac=nroaux;
		}	
	}
	
	println!("MAC {}", nromac);
	// (nromac outside the for gets Null)

this code below works, but does not work in a function:

fn getdatafromcmd(fcomando: &str) -> String {
    let resultado = Command::new("cmd")
        .arg("/C")
        .arg(fcomando)
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .output()
        .expect("failed to execute process")
    result resultado;	
}

Sorry - I've used bold in the post here in the forum, and then a lot of lines became with **** in the beginning

Please edit your post in a more readable way by wrapping the error text in a code snippet, and try to be clearer about what do you need help with; it should be so much easier for people trying to help you if they understand what the problem is, rather than reading a complaint and an allegedly extensive experience in software development.

8 Likes

If you want help with some of those specific errors, please create a minimum reproduction.

But just on the general "Rust is difficult" theme: yep, Rust is difficult to learn :slight_smile: I had 15 years of C++ under my belt when I started to learn Rust, and it still took me 6 months to really get comfortable with it. But the strictness of the language - which initially is so annoying - becomes the source of Rust's immense power. You just need to persevere (and ask for help here when needed!)

4 Likes

Where did you get this code from? This doesn't look like any form of documentation as it contains over 450 lines of code. Most compile errors seem to come from this line:

let mut discos: [str; sys.disks().len()] = [0; sys.disks().len()];

which is clearly wrong in several places:

  • An array stores its length in Rust at compile-time, allowing it to be fully stored on the stack. One cannot compute the amount of disks of a given system during compilation, thus the length cannot be known and this type does not work.
  • The array should store a fixed number of strs. A str is an unsized type and cannot be stored without indirection (e.g. &str, Box<str>, etc.), so this can't work.
  • Finally, the initializer does the same mistake of assuming sys.disk().len() can be calculated at runtime, and also tries to initialize the array with all zeros. This again clearly cannot possibly work, as a number is not a variably-long UTF-8 string.

The compiler has successfully identified all of these issues and has reported them human-readably, but I hope it became clear how utterly wrong the code was.


This does not work because it would be extremely inefficient: a chain of "a" + "b" + "c" + "d" + "e" would have quadratic complexity and many unnecessary allocations: &str, the default literal string type, does not own its contents and a new String would have to be created every time the + operator is used. Thus, you have to write the following:

let name = "John".to_owned() + " Doe";

which is both more performant and also shows how it actually works (explicitness).


I am going to assume that you wanted to type return instead of result in the second-to-last line. If you format and run the program you get the following error message:

error[E0308]: mismatched types
  --> src/lib.rs:12:12
   |
4  | fn getdatafromcmd(fcomando: &str) -> String {
   |                                      ------ expected `String` because of return type
...
12 |     return resultado;
   |            ^^^^^^^^^ expected `String`, found `Output`

For more information about this error, try `rustc --explain E0308`.

This error message should be perfectly understandable: you are trying to return an std::process::Output yet the code shows that the function should return a String. Thus, this function can't compile - it's really that simple. Rust, unlike many other languages you have used, actually provides error messages that directly show how to fix the error: either change the return type to Output or extract a String and return that.

13 Likes

I would prefer ["John", " Doe"].concat() because it can optimize to make a single allocation that will fit all the parts.

2 Likes

Hmm.. I have no idea what you want there but you have created three nromacs there by using let. One is outside the scope of the for loop and is always an empty string.
The second one is in the scope of the for loop and so will be used instead of the outer one.
But then you create a third one, again inside the scope of the for loop, that will hide the second one. This is called "shadowing". Presumably you get a warning about an unused nromac.

If you only want one nromac, as I suspect, then don't create new ones, remove the let.

I don't see how this aspect of the code at least could be much easier.

Rust does a lot to show you errors at compile time where they would show up (probably) as a runtime error much further down the line.

There's swings and roundabouts to this. On the one hand, it's harder to write your code and get it running quickly. On the other hand, it's harder to write buggy code and get it running quickly.

Now I'm (from what I can see in this thread) like you, in that I'll write code thinking "yup that'll work" only to be proven wrong time and time again. So I appreciate Rust pointing out my mistakes before I run it; much better than reading stack traces at 3am...

Of course, it's not a silver bullet. It is still possible to write (and run) buggy Rust code. It's still a lot harder than writing and running buggy Python.

3 Likes

Unlike golang, python, javascript, etc, you probably can not write rust code before you really know what you are doing exactly.

I also copy and paste many code in other languages, but not OK in rust. LOL.

It is true that many crates are broken, because maintainers may have abandon; User can only create a fork and repair them.

nice method, but it involves extra allocation?

It allocates extra array on stack, but most of the time it's more efficient than doing two allocation of heap objects (like version with to_owned is doing).

Which means that most of the time it's the most efficient way. Just compare code generated for two versions, it's obvious which one is more efficient just from the amount of code generated.

These errors indicates that you do have those experience of programming, but not adapted to programming without runtime, and the way writing Rust code. I guess you haven't been in contact with rust for long.

We just discussing about this code:

let mut discos: [str; sys.disks().len()] = [0; sys.disks().len()];
  1. str has the data structure same to [u8]. Note that [u8] has a dynamic size, so str not implements Sized, so str cannot be the type of an array's elements.
  2. Although zeroed array is a valid utf8 string (thanks @H2CO3 for mention), better not treat a &mut str as a buffer, it should be &mut [u8]. Converting a &[u8] to &str needs validation checking, I'm not familiar with utf8 encoding, don't know whether residual characters affect the checking, at least the checking overhead is there. Besides, string in Rust stores different than C's, \0 is not be considered as an end to a string. Also take a look at smallvec and smallstr on crates.io, or just use Vec simply.
  3. The length of this array is unknown in compile time. I don't know what sys.disk().len() exactly means, but it looks likes you trying to get a value from a temporary variant, whose length can only be known in runtime. Note that this is not Rust's fault, everything on stack has a fixed size, obviously the size of the array you are trying to create depending on the variant when running.
  4. Once you resolved above problem, the error says str doesn't implements Copy disappear automatically. Because it is u8 but not str should be here.

Another tip, please use format! to concat strings, not insert + between them.

These errors are always encountered by beginners, no matter they learned other language or not. Just keep learning. Welcome to Rust.

It is; 0 is just ASCII NUL, of which any amount is valid ASCII and by extension valid UTF-8.

My fault, thanks. But in my mind, although it is a valid utf8 string, but continuous 0s have no meaning, does it?

What particular kind of meaning do you have in mind?

I think 0 is exists to indicate an end of a C string. But in Rust mechanism, the length of a string is recorded as a usize, in the metadata of that string's pointer or somewhere else. so I think 0 character is useless in Rust, and should not appears in any position except the end of any C string.

Since NUL is a valid ASCII (and by extension UTF-8) character, they're valid to occur in regular Rust Strings which can contain any valid UTF-8 sequence.

But Rust does provide the CString type which has the added restriction of containing only a single NUL and only at the end, which makes it easier to interoperate with C strings.

2 Likes

No, that would be the case if strings were 0-terminated.

Since Rust's strings aren't 0-terminated, NUL characters are allowed to appear anywhere.

It does not. ASCII standardization predates C by about a decade so none of its defined codes, including NUL, can possibly exist for the purpose of supporting C— It didn’t exist at the time.

2 Likes

I wouldn't expect that temp array to survive optimization