On Thursday, 28 January 2016 at 13:36:46 UTC, Puming wrote:
I searched the forum and found that people use `const(char)[]` or `in char[]` to accept both string and char[] arguments.

There's also the hyper-generic signatures Phobos uses like

void foo(S)(S s) if(isSomeString!S)

and the input range types and the isConvertibleToString, etc., if you want to take different encodings, or string-like objects, or string wrappers/generators, etc.

But for just both string and char[], yeah, const is the way to do it.

What's the difference between `const(char)[]` and `in char[]`?

`in char[]` means the whole parameter is const and you are not supposed to escape it. It expands to `const scope char[]`, with the const on the outermost level and `scope` too which means a reference to it should never escape this scope.

const(char)[] global;

void foo(const(char)[] arg) {
   arg[0] = 'a'; // illegal, the contents are const
   arg = "whole new thing"; // legal, you are allowed to rebind
   global = arg; // legal, you can escape it too
}



contrast with:


const(char)[] global;

void foo(in char[] arg) {
   arg[0] = 'a'; // illegal, the contents are const
   arg = "whole new thing"; // illegal, arg is const too
   global = arg; // illegal, you can't escape the reference either
}



Note that the `global = arg` will still compile - the compiler doesn't properly check this right now - but the spec says it is illegal and may be optimized or statically checked differently at any time, so if you do it you are in undefined behavior territory. Don't do it!


If they are not the same, then which is better? If they are, then why both forms exists?

I like `in char[]` if you intend to follow all the rules. Otherwise, use the const version, which cannot be aliased because it isn't a type , it is a parameter storage class and only valid in that context.

Reply via email to