www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What is the best declaration type for a string like parameter?

reply Puming <zhaopuming gmail.com> writes:
I have a function that reads a line of string and do some 
computation.

I searched the forum and found that people use `const(char)[]` or 
`in char[]` to accept both string and char[] arguments.


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

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

I found it a bit confusing and not quite readable, so I made an 
alias:

alias str = const(char)[]

and so far it works. But if `in char[]` is better, then I cannot 
alias it:

alias str = in char[]

this does not compile.
Jan 28
next sibling parent reply sigod <sigod.mail gmail.com> writes:
On Thursday, 28 January 2016 at 13:36:46 UTC, Puming wrote:
 I have a function that reads a line of string and do some 
 computation.

 I searched the forum and found that people use `const(char)[]` 
 or `in char[]` to accept both string and char[] arguments.


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

 If they are not the same, then which is better? If they are, 
 then why both forms exists?
`in char[]` is short for `scope const char[]` or `scope const(char[])`. See http://dlang.org/spec/function.html#parameters It depends on the situation. If possible I would use `in` modifier. If not then just `const`.
 I found it a bit confusing and not quite readable, so I made an 
 alias:

 alias str = const(char)[]

 and so far it works. But if `in char[]` is better, then I 
 cannot alias it:

 alias str = in char[]

 this does not compile.
Please, don't define such aliases. I'm sure a lot of developers will find it confusing. As I do. `const(char)[]` or `in char[]` is perfectly understandable as soon as you know what it means. Also, read this: http://dlang.org/spec/const3.html
Jan 28
parent Puming <zhaopuming gmail.com> writes:
On Thursday, 28 January 2016 at 15:03:38 UTC, sigod wrote:
 On Thursday, 28 January 2016 at 13:36:46 UTC, Puming wrote:
 [...]
`in char[]` is short for `scope const char[]` or `scope const(char[])`. See http://dlang.org/spec/function.html#parameters It depends on the situation. If possible I would use `in` modifier. If not then just `const`.
 [...]
Please, don't define such aliases. I'm sure a lot of developers will find it confusing. As I do. `const(char)[]` or `in char[]` is perfectly understandable as soon as you know what it means. Also, read this: http://dlang.org/spec/const3.html
Thanks. Now I get it. Yes it is understandable now, but as a newbie the question "Why my function that accepts a string does not work with lines in file?" will pop.
Jan 28
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Jan 28
next sibling parent reply Gary Willoughby <dev nomad.so> writes:
On Thursday, 28 January 2016 at 15:10:38 UTC, Adam D. Ruppe wrote:
 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)
Yep, this is your answer. void foo(S)(S s) if(isSomeString!S) { //use s } Call normally as it can implicitly determine the type of S: foo("bar");
Jan 28
parent tsbockman <thomas.bockman gmail.com> writes:
On Thursday, 28 January 2016 at 17:32:31 UTC, Gary Willoughby 
wrote:
 On Thursday, 28 January 2016 at 15:10:38 UTC, Adam D. Ruppe 
 wrote:
 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)
Yep, this is your answer. void foo(S)(S s) if(isSomeString!S) { //use s } Call normally as it can implicitly determine the type of S: foo("bar");
Template bloat awaits those who take this approach to every problem. In practice, `in char[]` is probably better for most code.
Jan 28
prev sibling parent Puming <zhaopuming gmail.com> writes:
On Thursday, 28 January 2016 at 15:10:38 UTC, Adam D. Ruppe wrote:
 But for just both string and char[], yeah, const is the way to 
 do it.

 [...]
Thanks for the clear explaination. So `in char[]` is stricter (and safer) than `const(char)[]`. I will stick to that.
Jan 28