#Concat-ing 2 slices without allocating

1 messages · Page 1 of 1 (latest)

hollow terrace
#

can't you just use ```rs
std.debug.print("[app] {} ({any}ms)\n", args ++ .{msg, std.time.milliTimestamp()});

#

i might've typed that wrong tho

#

ah

#

can you format the msg with fmt?

#

ah that would make msg no longer comptime maybe

#

does ++ work on struct literals or is args an array literal?

#

i did write my own non-comptime print once and dug right through how fmt handles its args

#

what error do you get? i'm not very fluent in zig yet as you can tell but it is kinda interesting

#

afaik you can only concatenate in the true sense if both are comptime and neither args nor std.time.milliTimeStamp() are comptime

#

but in the wider sense i'm not sure you may be able to print the two things adjoining

#

basically you'e adding an arg to args right?

#

one of the ways .print avoids allocating is that it uses I think a u8 as a bitmap and has a maximum 256 arguments

#

i wanted to manipulate it to work with different fmt strings that had different numbers of {} but not get errors about extra or unused args

#

(-:

#

i thought 256 sounded too much hehe

mossy relic
#

What are you passing in to args?

#

Hmmm

hollow terrace
mossy relic
#

Small nit: .{} is a tuple, a slice is a pointer and a len, usually you get 'em from the array[1..] syntax

#

I don't think so

#

I'm suspect of either version difference or argument difference

#

since it's anytype

hollow terrace
#

yeah i was wondering about .{} vs literal struct/array

devout timber
#

.{} can be an array or a tuple, depending on the type of the destination.

#

If the dest is an anytype argument, then it'll be a tuple.

#

You can make an immutable slice with &.{} though.

hollow terrace
devout timber
#

(A tuple is basically just an array, but where the values can be of different types.)

mossy relic
#

Bah, I'll get it fully right one day

devout timber
#

It might be more useful to consider them an array as I said, because of that.

#

But tuples are, in a more literal sense, a structure without names for its fields, yeah.

hollow terrace
#

ah that's right. can you pass a tuple literal to a function expecting a struct? i forgot. .{} always feels overloaded and hard for newbie me. especially when including &.{}

devout timber
#

You'd need .{ .name = value } rather than .{ value }.

hollow terrace
#

ah OK

devout timber
#

Which makes sense; how would it know what field to assign to? Considering Zig wants to be easy to read and explicit, it wouldn't want to just assume their in order.

#

If args is a tuple, then it may work.

mossy relic
#

You can pass an anonymous struct: .{ .x = 4, .y = 8}, so long as the fields match (where a named struct is required)

hollow terrace
#

after you implement it with alloc you'll have a sudden eureka (-:

devout timber
#

If it's a slice, you'll have to do something else.

mossy relic
#

It's all about coercing correctly

#

@cinder furnace Are you on linux and what's your zig version?

#

I have to wonder if 0.10.0 release would behave differently then

devout timber
mossy relic
#

ahhhhh

#

What does the function calling print return?

#

runtime or comptime known lengths is the key bit

devout timber
#

No. On 0.10 and before, tuples had to be comptime known in entirety for ++. Now they only need to have a comptime size. i.e: You can concatenate two arrays with it, for example.

#

I'm not entirely sure that they've fully implemented tuple concat, but the code above works if you change them both to vars - so you may be good with it.

#

Can confirm; this works fine:

var glob: usize = 99;
fn myfmt(comptime fmt: []const u8, args: anytype) void {
    const new_args = args ++ .{ glob };
    const add_nl = fmt[fmt.len - 1] != '\n';
    const new_fmt = fmt ++ " ({})" ++ if(add_nl) "\n" else "";
    print(new_fmt, new_args);
}

pub fn main() void {
    myfmt("there are {} stars in the sky", .{ 99_105 });
    // prints: 'there are 99105 stars in the sky (99)'
    // and puts a newline
}