繁体   English   中英

如何在 Zig 中创建类型化索引

[英]How can I make a typed index in Zig

我有一个算法,它有两个具有各自索引的数组。 只是,很容易混合两个索引并访问具有错误索引的数组之一。 例如:

var array1 = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
var index1 = 7; // the 8th element in array1, fine because array1 has a length of 10
var array2 = [_]u8{ 1, 2, 3, 4, 5 }; 
var index2 = 2; // the 3rd element in array2, fine because array2 has a length of 5
array2[index1] // woops, I used the wrong index with the wrong array

有没有办法让自定义索引类型将数组与特定类型的索引相关联,这样使用错误类型的索引索引数组会导致编译错误? 如:

var array1 = [_:Index1]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // with index type 'Index1'
var index1 : Index1 = 7; // index of type 'Index1'
var array2 = [_:Index2]u8{ 1, 2, 3, 4, 5 }; // with index type 'Index2'
var index2 : Index2 = 2; // index of type 'Index2'
array2[index1] // ERROR: array2 expects Index2 type index but Index1 type is used
const std = @import("std");


fn PickyArray(comptime T: type, n: usize, extra: anytype) type {
    _ = extra;
    return struct {
        const Self = @This();
        pub const Index = struct {
            idx: usize,
        };
        unsafe_items: [n]T,
        pub fn init(xs: [n]T) Self {
            return .{.unsafe_items = xs};
        }
        pub fn get(self: Self, idx: Index) T {
            return self.unsafe_items[idx.idx];
        }
        pub fn set(self: *Self, idx: Index, v: T) void {
            self.unsafe_items[idx.idx] = v;
        }
        pub fn getPtr(self: Self, idx: Index) *T {
            return &self.unsafe_items[idx.idx];
        }
        pub fn getSlice(self: Self, lo: Index, hi: Index) []T {
            return self.unsafe_items[lo.idx..hi.idx];
        }
    };
}

const Array1 = PickyArray(u8, 10, "Index1");
const Index1 = Array1.Index;
const Array2 = PickyArray(u8, 5, "Index2");
const Index2 = Array2.Index;

pub fn main() void {
    var array1 = Array1.init([_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
    var index1 : Index1 = .{.idx=7}; // index of type 'Index1'
    var array2 = Array2.init([_]u8{ 1, 2, 3, 4, 5 }); // with index type 'Index2'
    var index2 : Index2 = .{.idx=2}; // index of type 'Index2'
    _ = array2.get(index1); // ERROR: array2 expects Index2 type index but Index1 type is used
    _ = array1;
    _ = index1;
    _ = array2;
    _ = index2;
}

对于额外的功劳, getSlice返回的类型不应该是普通切片,并且应该拒绝接受整数索引。

请不要这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM