Understanding `usingnamespace`

I’ve been trying to wrap my head around the usingnamespace keyword in Zig. I understand that it is used to import definitions of a struct or file into the current scope.

What I don’t understand is why after I import a something (say std), I have to use the @This() thing to access the definitions. Why’s this?

Let me give a concrete example:

// main.zig
usingnamespace @import("std");

// I expect to be able to just do
// log.debug("All your codebases are belong to us!", .{});
// But it doesn't work

What I get is use of undeclared identifier 'log'
I was expecting all the public definitions to already be a part of the current scope and not need a prefix like @This(). Is there something I’m missing?

The language used to behave like you’re expecting it to, but it was changed to how it behaves now I believe in 0.9. This issue goes into the details of why this was changed. My take on this is that the new behavior is more aligned with Zig’s philosophy of always being explicit, knowing where everything comes from and what everything is doing just by looking at the code. Harder to write? perhaps, but we all spend much more time reading the code so I think it’s worth it.

The idea is that you should not use usingnamespace to get namespaceless (unqualified?) access to identifiers from your imports, but rather it’s only to expose a unified namespace to your users.

Reading the explanations here, I now understand why usingnamespace works the way it does.

Thanks very much!

1 Like