3 ms·
> let &mut writer = Writer<T>::writer::new(connection.clone()).clone(); // TODO ??? writer.write(data.clone()).unwrap(); It's not difficult to arrive at the ca
by inejge 3y ago
> let &mut writer = Writer<T>::writer::new(connection.clone()).clone(); // TODO ??? writer.write(data.clone()).unwrap();
It's not difficult to arrive at the caricature of baroque generic code if you combine lack of knowledge with miscommunication. The knowledgeable coworker should be aware that a writable object implements the Write trait, and know, or find out, the signature of the Write::write() method. Even fully generic, a function accepting a connection and returning the result of writing a block of data is not too gnarly:
use std::io::{self, Write};
fn write_data<W: Write, D: AsRef<[u8]>>(connection: &mut W, data: D) -> io::Result<usize> {
connection.write(data.as_ref())
}
No unwraps, no clones. Because they're not necessary here. But someone has to know the language and the idioms. Even your "easy" C++ code depends on knowing that write() returns zero on success, and that integers can play the role of booleans in conditions.*
- inejge 3y agoEh, zero on failure, I suppose. The real write(2) syscall returns -1 on failure, and a non-negative value is the number of bytes actually written. But the general point still stands.
- sgtnoodle 3y agoWhen I wrote my hypothetical example, I was imagining the return type to be a bool. My apologies for overloading "write", a more representative example function name would have been something like "FooWrite". I appreciate your follow-up! I totally agree with you that folk writing code need to understand the semantics of what they're building on top of. Humans and now AI models have a great capacity for generating tons source code without understanding the semantics, though.