Default fields make sense when you can change fields independently of each other.
But if doing so can cause an invalid state, a declaration is preferred as it prevents that.
Declarations also provide a clear name to the state, there can be multiple, and can coexist with default fields.
For that specific question, it shouldn’t be .unlocked because a user shouldn’t do, for example:
my_lock.lock();
defer my_lock = .unlocked;
That is, .init should only be used for initialization, so it is named as such.
In general, it seems the consensus of the core team is that default fields are only the way to do things in a few specific cases, and initialization of variables tends to not be one of them. The main “rule” is that you should not use default fields if setting one of the fields but not another has the potential for the struct to be initialized in an invalid state. This has cascaded in a general style change of using decl literals for “default” initialization across the std, which includes the mutex. Another advantage is that this gives an explicit API surface point of “this is how you initialize this” instead of just knowing that an empty initialization (.{}) is a usable construct.
As far as I understand it, the only reason default field values are still in the language at all is because they’re really useful for options structs.
Something that might remove the need for defaults is if you could do .default with .{ .foo = 10 }. I’m not sure the caveats and footguns of a system like that, but in the very least it’s trivially implementable in userspace.