这个周末在改进 libcurl 的 Zig 封装,一直不太满意现在的 API 设计,比如现在的 fetch 接口,有如下两种形式:
/// Fetch issues a request to the specified URL.
pub fn fetch( self: Self, url: [:0]const u8, resp_buffer: ?[]u8, options: FetchOptions, ) !Response
/// Fetch issues a request to the specified URL. Response body is allocated dynamically.
pub fn fetchAlloc( self: Self, url: [:0]const u8, allocator: Allocator, options: FetchOptions, ) !Response
很明显,第一个需要用户自己分配内存,第二个由 Allocator 分配,按说这样情况都考虑到了,但是这两种情况都是在内存中写数据,如果请求的返回结构很大,如果直接在内存攒批明显是种不好的方式,最好的方式是可以把写入的方式抽象成一个接口,比如:
writeFn: * const fn(data: []const u8) usize
这样用户自己处理数据就完全由用户控制了,最终的 API 如下:
/// Set `WRITEDATA` to context and `WRITEFUNCTION` to a function that calls with the context.
pub fn setWriteContext(
self: Self,
context: anytype,
comptime writeFunc: fn (@TypeOf(context), ptr: []const u8) usize,
) !void {
try self.setWritedata(context);
try self.setWritefunction(struct {
fn write(ptr: [*c]c_char, size: c_uint, nmemb: c_uint, user_data: *anyopaque) callconv(.C) c_uint {
const real_size = size * nmemb;
const ctx: @TypeOf(context) = @alignCast(@ptrCast(user_data));
const data = ptr[0..real_size];
return @intCast(writeFunc(ctx, data));
}
}.write);
}
本以为大功告成了,没想到提 GitHub PR 后,Gemini Code Assist 给我提了这么一个问题:
不得不说,Gemini 理解 Zig 代码的能力真是强!推荐大家在自己的项目上都开启 Gemini Code Assist,完全免费!🍺 详见:
加入我们
Zig 中文社区是一个开放的组织,我们致力于推广 Zig 在中文群体中的使用,有多种方式可以参与进来:
- 供稿,分享自己使用 Zig 的心得
- 改进 ZigCC 组织下的开源项目
- 加入微信群
这个周末在改进 libcurl 的 Zig 封装,一直不太满意现在的 API 设计,比如现在的
fetch接口,有如下两种形式:很明显,第一个需要用户自己分配内存,第二个由 Allocator 分配,按说这样情况都考虑到了,但是这两种情况都是在内存中写数据,如果请求的返回结构很大,如果直接在内存攒批明显是种不好的方式,最好的方式是可以把写入的方式抽象成一个接口,比如:
这样用户自己处理数据就完全由用户控制了,最终的 API 如下:
本以为大功告成了,没想到提 GitHub PR 后,Gemini Code Assist 给我提了这么一个问题:
不得不说,Gemini 理解 Zig 代码的能力真是强!推荐大家在自己的项目上都开启 Gemini Code Assist,完全免费!🍺 详见:
加入我们
Zig 中文社区是一个开放的组织,我们致力于推广 Zig 在中文群体中的使用,有多种方式可以参与进来: