Ошибка при добавлении преобразованного u8 (из i8) в ArrayList только в определенной программе

Мне нужно преобразовать число i8 в u8 (@intCast()), чтобы оно было добавлено в ArrayList (мне все равно, как это преобразование будет выполнено, если число отрицательное).

Запуск этой программы с zig test intcast.zig возвращает All 1 tests passed.:

const std = @import("std");

const SIZE = 30_000;

test "Convert i8 to u8" {
    var memory :[SIZE]i8 = [_]i8{65} ** SIZE;
    var memory_index: u32 = 10;
    var output = std.ArrayList(u8).init(std.heap.page_allocator);
    defer output.deinit();

    try output.append(@intCast(u8, memory[memory_index]));

    std.testing.expectEqualSlices(u8, "A", output.items);
}

Но когда я пытаюсь использовать ту же процедуру в другой программе, она не работает, компилятор возвращает мне следующую ошибку:

≻ zig test bf.zig
./bf.zig:15:22: error: expected type '[30000]i8', found '@TypeOf(std.array_list.ArrayListAligned(u8,null).append).ReturnType.ErrorSet'
            '.' => { try output.append(@intCast(u8, memory[memory_index])); },

Вот программа, и здесь я добавляю преобразованное число:

for (program) |command| {
    switch (command) {
        '+' => { memory[memory_index] += 1; },
        '-' => { memory[memory_index] -= 1; },
        '.' => { try output.append(@intCast(u8, memory[memory_index])); },

Пожалуйста, кто-нибудь может сказать мне, что я делаю неправильно?

Мой зиг 0.6.0+8b82c4010.


zig
person paulohrpinheiro    schedule 11.07.2020    source источник


Ответы (1)


Это не имеет ничего общего с intCast, проблема в том, что возвращаемый тип функции не допускает возможную ошибку

fn execute(program: []const u8) [MEMORY_SIZE]i8 {
    for (program) |command| {
        switch (command) {
            '+' => { memory[memory_index] += 1; },
            '-' => { memory[memory_index] -= 1; },
            '.' => { try output.append(@intCast(u8, memory[memory_index])); },
//                   ^^^ try wants to return an error, but
//                       the function's return type is [30000]i8
//                       which cannot be an error
    ...
}

Простое исправление: разрешить функции возвращать ошибку

fn execute(program: []const u8) ![MEMORY_SIZE]i8 {

Ошибка не очень хороша для этого прямо сейчас, но если вы внимательно посмотрите на найденный тип, что-то пытается преобразовать из @TypeOf(...).ReturnType.ErrorSet в [30000]i8, и это невозможно сделать. Однако можно преобразовать из @TypeOf(...).ReturnType.ErrorSet в ![30000]i8.

try something() эквивалентно something() catch |err| return err;, откуда и возникает ошибка типа.

person pfg    schedule 14.07.2020
comment
Большое спасибо за решение, ваше объяснение очень помогло, в основном потому, что я начинаю изучать язык зиг. - person paulohrpinheiro; 14.07.2020