应键入“i32”,找到“usize”

expected type 'i32', found 'usize'

提问人:ZeroTerabytes 提问时间:6/2/2023 更新时间:6/2/2023 访问量:752

问:

我目前正在尝试解决 Zig 中的一些 leetcode 问题,我正在做两个总和问题。下面是我的整个代码的样子:

const std = @import("std");
const allocator = std.heap.page_allocator;

fn two_sum(nums: []i32, target: i32) []i32{
    var map = std.AutoArrayHashMap(i32, i32).init(allocator);
    defer map.deinit();
    var res = [2]i32{-1, -1};
    for (nums, 0..) |n, i| { // n is the number; i is the index
        if (map.get(target - n)) |v| {
            res[0] = v;
            res[1] = @as(i32, i);
            return &res;
        }
        try map.put(n, @as(i32, i));
    }
    return &res;
}

pub fn main() !void {
    var arr = [_]i32{1, 5, 8, 9, 6};
    var x = two_sum(&arr, 9);
    for (x) |n| {
        std.debug.print("{d}", .{n});
    }
}

但是,当我运行代码时,出现以下错误:

error: expected type 'i32', found 'usize'
            res[1] = @as(i32, i);
                ^

为什么 zig 将 1 解释为 a 而不是 an ?可以做些什么来解决这个问题?usizei32

我尝试使用显式类型转换: res[@as(i32, 1)] = @as(i32, i);

然而,这也没有用。

阵列 铸造 之字形

评论

0赞 Ali Chraghi 6/2/2023
我无法用最新的 Zig (master) 重现这一点

答:

4赞 ad absurdum 6/2/2023 #1

最直接的问题是 has type ,并且您无法从 cast from 转换为 use,因为 an 无法保存 a 可能包含的所有值。相反,当您知道石膏是安全的时,请使用专门针对这些情况的@intCast。有两个这样的强制转换需要更改为 .iusizeusizei32@asi32usize@as@intCast

该函数需要返回一个错误联合,因为它在调用 时使用。由于需要返回错误联合,因此调用需要处理该联合,例如,通过使用 .two_sumtrymap.puttwo_sumtwo_sumtry

最后,是一个局部变量,不应返回指向局部变量的指针;在控件离开局部作用域后,与局部变量关联的存储无效,并且尝试访问此类无效内存会导致未定义的行为。无需返回指针,只需返回数组(副本)。res

这是具有上述更改的 OP 发布代码的一个版本。

const std = @import("std");
const allocator = std.heap.page_allocator;

fn two_sum(nums: []i32, target: i32) ![2]i32 {  // return error union
    var map = std.AutoArrayHashMap(i32, i32).init(allocator);
    defer map.deinit();
    var res = [2]i32{ -1, -1 };
    for (nums, 0..) |n, i| {
        if (map.get(target - n)) |v| {
            res[0] = v;
            res[1] = @intCast(i32, i);     // use `@intCast` instead of `@as`
            return res;                    // just return the array
        }
        try map.put(n, @intCast(i32, i));  // use `@intCast` instead of `@as`
    }
    return res;                            // just return the array
}

pub fn main() !void {
    var arr = [_]i32{1, 5, 8, 9, 6};
    var x = try two_sum(&arr, 9);  // `two_sum` returns an error union
    for (x) |n| {
        std.debug.print("{d}", .{n});
    }
    std.debug.print("\n", .{});
}