#Zigling Questions about slices and errors

1 messages · Page 1 of 1 (latest)

mental stream
#

From Ex 52 about slices, the comments state that "// The type of a slice on an array of u8 items is []u8."
But, in order to store slices of length 4 i had to declare the variables as:
"const hand1: *[4]u8 = cards[0..4];" since the slice is of type *[4]u8, and define the function parameters to be the same. So is the comment incorrect or was it expecting a different solution?

Also, a question about errors: one of the early exercises wanted me to use a 'try' statement without much elaboration, and multiple errors were possible. I tried various ways to do if-statements to report based on the type of error encountered, but kept running into type issues with the conditionals. So, if using the shorthand try, is it possible to handle each error case differently or do i have to use the 'catch' syntax for that?

Thanks in advance

#

Zigling Questions about slices and errors

flat jasper
#

When you slice by comptime known bounds, Zig will actually make it a pointer to an array. So cards[0..4] is of type *[4]u8, since it has a comptime known length of 4. This will coerce into a slice ([]u8)

#

Since it coerces, you could do const hand1: []u8 = cards[0..4];

#

Try's behavior is pretty much the same as catch |err| return err;. If you want to handle specific errors, then you would catch it and do your checks on the error, for example:

const foo = fallableFunction() catch |err| switch (err) {
    error.A => {},
    error.B => {},
    else => return err,
};```The type errors you were likely getting is that the prongs where you don't break/return will return a value which will then be assigned to the result. Here prongs `error.A` and `error.B` try to assing `foo` to be `void`
#

The reason you don't get these type conflicts with a return in the error path is that is because a return statement has the type noreturn which coerces into anything

mental stream
#

For the errors, the exact code I tried were variations of :

pub fn main() void {
    const a: u32 = addFive(44) catch 0;
    const b: u32 = addFive(14) catch 0;
    const c: u32 = addFive(4) catch 0;

    std.debug.print("a={}, b={}, c={}\n", .{ a, b, c });
}

fn addFive(n: u32) MyNumberError!u32 {
    // This function needs to return any error which might come back from detect().
    // Please use a "try" statement rather than a "catch".
    //
 const x = try detect(n);
    if (x == MyNumberError.TooSmall) {
        return MyNumberError.TooSmall;
    }
    if (x == MyNumberError.TooBig) {
        return MyNumberError.TooBig;
    }
    return x + 5;

With the error: operator == not allowed for type 'error{TooSmall,TooBig}!u32'

It makes sense why it doesn't work. Is it accurate to say that we use try so that we can just deal with any errors in the main function and not clutter every function with switch statements?

#

and the proper way to handle these errors would be to change the catch 0 in main?

flat jasper
#

Use try when it doesn't make sense to handle the error inside the function

#

For example, if it didn't make sense to have a default value in the error path for the calls to addFive, you could write

pub fn main() !void {
    const a = try addFive(44);
    -- snip --
}```
#

Since you've decided there's no sensible way for you to handle the error, you panic