|
|
|
|
|
by fredmorcos
3738 days ago
|
|
Yes! That definitely reinforces my understanding. So Rust is more like C and less like C++ in that it is pass-by-value everywhere, with the exception that references are not pointers but _real_ references. Does this make things like "const int * const x" (in C syntax) pointless in Rust? Does that mean that in Rust I can only pass to a function an immutable reference to a mutable object, but not a mutable reference to an immutable object? Also, out of curiosity, how would something like a recv() call into the middle of an array (buffer) look like in rust? Something like "recv(sock_fd, buf + 5 * sizeof(char), buf_len - 5 * sizeof(char), 0)"? |
|
The variations are:
More mutablity == longer declaration, roughly. You're right in both. No problem treating something mutable as immutable, but treat something immutable as mutable and you get a compiler error. Rust has a concept called "slices". These are "fat pointers", that have both a pointer and a length inside: Here, 'slice' will be a pair, (ptr, len), so the ptr will point to the interior of the vector, and the length will be 2. If we printed it, we'd see "2, 3".So let's check out the signature of recv:
This pointer, length pair looks suspiciously like buf and len here. That's for good reason. A first step towards a more Rust-like wrapper over recv would look like this: which would end up being called like this: combining the names from your example and mine from the slice above, heh.The next step would be to turn `flags` into an enum, and take that as an argument rather than a C int. Then you'd want to convert the return type to a Rust integer rather than a C one... eventually, you end up with the API we have in the standard library, which looks like this for a udp socket, for example:
A few comments on this:We only said &mut buf, but I showed you syntax with [] above. When you pass a reference to an array or vector, and the function is expecting a slice, it will automatically convert to a slice of the full length. To be more accurate to your original question:
or whatever middle part of the buffer you want.amt is the amount of bytes read, and the src is the address, in this particular API.
You'll notice this particular API doesn't expose flags: we try to Do The Right Thing in the standard library, so you don't worry about these. Here's the source of rec_from: https://github.com/rust-lang/rust/blob/master/src/libstd/sys... c::recvfrom is libc::recvfrom, rather than recv, technically. But as an example from a different API, when opening files, we set O_CLOEXEC where appropriate: https://github.com/rust-lang/rust/pull/27971
If you want the more exotic options, then you have to dig in and make the calls yourself. Such is the pain of a standard library, trying to make the common, good case good, but we still let you dig in and build a different abstraction if you don't like ours.