Global mutable slice?

In the examples file for my gui library, I want to declare a global mutable slice ([]u8) to use in a text entry field that starts filled with some example text. Here’s the best I’ve come up with:

var mutable = "abc".*;
var mutable_slice = &mutable; // mutable_slice is []u8

Is there any way to make this a single line?

Hey @david_vanderson, check out this thread here for some related information: How to anonymously initialize a slice?

In short, you cannot make a literal mutable. The thing that assigns from a literal (the copy) can be mutable but the literal itself is not. Because of that, you’re basically going to initialize some memory (like you do on the first line) and then grab a slice to that memory (second line).

If you point directly at the literal, you need to have a constant pointer (non-mutable).

Also, just to point out… the var here means that the slice itself is mutable (you can redirect it at different memory), but you can do this:

const slice: []u8 = buffer[0..]; 

And you can still modiffy the underlying buffer. See this for more info: Mutable and Constant Pointer Semantics

I thought maybe there was some clever way to use a comptime block that I hadn’t been able to figure out, but sounds like no. Your explanation is very good, and I had not considered making the mutable slice const. Thank you very much!

EDIT: This code doesn’t work, see below.

    const mut_slice = init: {
        var hidden_array = [_]u8{ 'a', 'b', 'c' };
        break :init hidden_array[0..];
    };
    std.debug.print("{s}\n", .{mut_slice});
    mut_slice[1] = 'z';
    std.debug.print("{s}\n", .{mut_slice});

I get this error (same error for me on 0.13):
% ../../apps/zig-macos-aarch64-0.14.0-dev.1550+4fba7336a/zig run test.zig test.zig:3:25: error: global variable contains reference to comptime var const mut_slice = init: {

Here’s the full test.zig file:

const std = @import("std");

const mut_slice = init: {
        var hidden_array = [_]u8{ 'a', 'b', 'c' };
        break :init hidden_array[0..];
    };

pub fn main() !void {
    std.debug.print("mut: {s}\n", .{mut_slice});
}

My bad, that was previously allowed but not any more. I guess you would have to at least have the two lines:

var array = [_]u8{ 'a', 'b', 'c' };
const mut_slice = array[0..];

Phew - I was worried I was missing something obvious. Thanks!