// Copies slice `s` into the requested line
pub fn set_line(line: usize, s: []u8) !void {
if (line < 0 or line > winsize.row) {
return error.OutOfBounds;
}
if (s.len > winsize.col) {
return error.BufferTooBig;
}
// If the slice isn't as big as winsize.col then the line is first cleared
if (s.len < winsize.col) {
@memset(buffer[line], 0);
}
@memcpy(buffer[line], s);
}
The issue is I get the following error: panic: source and destination arguments have non-equal lengths
How would I copy s into buffer[line] even if buffer[line] is bigger than s?
That’s very ugly! I understand the concept of a slice of a slice but it is (probably) consuming more stack memory for the same thing and it looks like an array of arrays from C.
It is not a slice of a slice, don’t judge a construct before you understand it.
Edit: for me a slice of a slice is [][]u8 and similar, this just does slicing and re-slicing and because the compiler sees the two slicing operations after another it can treat them similarly to the other single slicing. I was speaking from the more general case where b is a multi-item pointer to begin with instead of a slice (which I admit was an oversight on my part) and in that case I find the double slicing operation much prettier than the arithmetic version, that was the main point I wanted to make.
The first part b[offset .. ] results in a slice multi-item pointer [*]u8 these pointers don’t have an associated length and the pointer points to the offset item, so this part does the offsetting.
The second part [0..s.len] re-slices the multi-item pointer, returning a slice and thus gives it a defined length. to the final length.
It is semantically and memory wise equivalent to the other way of writing it, but it avoids repeating offset twice and doing manual addition, further in contexts where the length is comptime known it has the added benefit of resulting in a pointer to array (instead of a slice), which is coerce-able to a slice, but doesn’t need to store the length because it is comptime known.
Thanks for the patronizing and pedantic statement, but your knowledge doesn’t seem consistent with what the compiler is giving me back.
You first statement doesn’t seem to be true, since b[offset .. ]does not result in a multi-item pointer [*]u8:
const c = b[offset..];
std.debug.print("{}", .{@TypeOf(c)}); // []u8
Your second statement also doesn’t seem true. The four combinations of (runtime, comptime) and (cool syntax, ugly syntax) return exactly the same instructions when using any release flag.
Also, my statement about consuming more memory seems accurate, but only when you are not using any release flag and comparing runtime versions of the function. In this case, you can see a difference from ugly syntax to pretty syntax in which case the pretty version do use less instructions and memory.
I can’t think of a use case where you’d want performance so much that you’d rather use slice[idx..idx + len] instead of slice[idx..][0..len], and still not use any release flag.