我对学习 Zig 完全是菜鸟,所以我的问题可能很天真。
std.fmt.allocPrint()
)在代码中创建各种字符串
当我一次只处理一个字符串时,它是有效的,但是当我决定将其抽象为一个函数时,编译器告诉我
allocPrint
的格式字符串是comptime
。
我找不到任何方法来使用运行时格式字符串来实现同样的事情。
是否有一种完全不同的方法,涉及不使用
std.fmt
,或者我是否因为是初学者而错过了一些基本的东西?
Zig 的打印函数需要编译时已知的格式字符串。如果需要动态字符串,可以使用C的printf。
这是我在版本 0.12.0-dev.2296+46d592e48 上运行的东西。
const c = @cImport({
@cInclude("stdio.h");
});
const std = @import("std");
// Returns a null-terminated heap-allocated string, usable in C, containing the phrase "hi " repeated numHis type.
const hi = "hi ";
fn getHis(allocator: std.mem.Allocator, numHis: usize) ![*:0]u8 {
const total_len = numHis * hi.len;
// allocSentinel ensures it ends with a \0.
const s = try allocator.allocSentinel(u8, total_len, 0);
var i: usize = 0;
while (i < total_len) : (i += hi.len) {
// repeatedly copy the phrase into the allocated memory.
std.mem.copyForwards(u8, s[i .. i + hi.len], hi);
}
return s;
}
// Returns a null-terminated heap-allocated string, usable in C, containing some border chars and the phrase "%s", which can be passed as a format string to c's printf.
const strInsert = "\n%s\n";
fn getBorderedFormatString(allocator: std.mem.Allocator, borderChar: u8) ![*:0]u8 {
const total_len: usize = 20 + strInsert.len + 2; // add 2 for leading and trailing newline
const s = try allocator.allocSentinel(u8, total_len, 0);
var i: usize = 0;
s[i] = '\n';
i += 1;
while (i < 11) : (i += 1) {
s[i] = borderChar;
}
std.mem.copyForwards(u8, s[i .. i + strInsert.len], strInsert);
i += strInsert.len;
while (i < total_len - 1) : (i += 1) {
s[i] = borderChar;
}
s[i] = '\n';
return s;
}
test "dynamic_phrase" {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
const s = try getHis(allocator, 30);
const f = try getBorderedFormatString(allocator, '+');
_ = c.printf(f, s);
}