1971 shaares
6 private links
6 private links
echo 'print __libc_dlopen_mode("/path/to/library.so", 2)' | gdb -p <PID>
Trait Basics
Self always refers to the implementing type.
- Use associated types when there should only be a single impl of the trait per type.
- Use generic types when there can be many possible impls of the trait per type.
In other words, we can't "clone" a &str into a String, or a &Path into a PathBuf, or an &OsStr into an OsString, since the clone method signature doesn't support this kind of cross-type cloning, and that's what ToOwned was made for.
&[u8] impls Read and that Vec<u8> impls Write so we can easily unit test our file handling functions using Strings which are trivial to convert to &[u8] and from Vec<u8>
If a type is Sized that means its size in bytes is known at compile-time and it's possible to put instances of the type on the stack.
1. All generic types get an implicit Sized bound.
2. Since there's an implicit Sized bound on all generic types, if we want to opt-out of this implicit bound we need to use the special "relaxed bound" syntax ?Sized which currently only exists for the Sized trait:
3. There's an implicit ?Sized bound on all traits.
If a type is Send that means it's safe to send between threads. If a type is Sync that means it's safe to share references of it between threads. In more precise terms some type T is Sync if and only if &T is Send.
Almost all types are Send and Sync. The only notable Send exception is Rc and the only notable Sync exceptions are Rc, Cell, RefCell. If we need a Send version of Rc we can use Arc. If we need a Sync version of Cell or RefCell we can Mutex or RwLock. Although if we're using the Mutex or RwLock to just wrap a primitive type it's often better to use the atomic primitive types provided by the standard library such as AtomicBool, AtomicI32, AtomicUsize, and so on.
/ scroll down a bit to avoid visual glitch when the screen
// area shrinks by one row
std::cout << "\n";
// save cursor
std::cout << "\0337";
// set scroll region (this will place the cursor in the top left)
std::cout << "\033[0;" << std::to_string(nr_rows - 1) << "r";
// restore cursor but ensure its inside the scrolling area
std::cout << "\0338";
static const char *move_cursor_up = "\033[1A";
std::cout << move_cursor_up;
printf >&2 '%s: reading from stdin...' "$(basename "$0")"
stdin=$(cat <&0)
printf >&2 '\r\033[0K'
echo "$stdin"
Mental exercises
"How about this: There is nothing simple, everything is learned. Everyone has to understand a software product and learn how to use it. They have to remember what they have learned, will forget things and relearn them. “Learning is work,” you will hear, “that sounds like stress, I have too much to do.” This is something we can work with. We need to reduce the amount of learning. I’d like to pick out three aspects that shape this effort."