Ошибка при добавлении преобразованного 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
.
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;
откуда и происходит ошибка типа.