I’m having trouble with this one.
How do you specify the type of a constructor parameter as an array? For example
def initialize(@contents : [] of String, @line : Int32, @position : Int32)
I’m having trouble with this one.
How do you specify the type of a constructor parameter as an array? For example
def initialize(@contents : [] of String, @line : Int32, @position : Int32)
def initialize(@contents : Array(String), @line : Int32, @position : Int32)
Well that was easy! Thank you very much Blacksmoke16
[] of T
Creates an empty array for values with type T
.
Array(T)
Is the type of an array for values with type T
While we’re at it I think it would be useful to make the compiler a bit smarter:
$ ./test.cr
Syntax error in test.cr:3: for empty arrays use '[] of ElementType'
def a(x : Array(Int32) = []) : Nil; end
$ ./test.cr
Syntax error in test.cr:3: for empty hashes use '{} of KeyType => ValueType'
def a(x : Hash(Int32, Int32) = {}) : Nil; end
Why does it make me repeat myself?
It says in the documentation: “Empty array literals always need a type specification”.
https://crystal-lang.org/reference/syntax_and_semantics/literals/array.html
But you can avoid repetition this way:
def a(x = [] of Int32); end
The type of the parameter will be infered from the default value.
Yes, it’s a bit repetitive. But it’s not clear how to allow that. Does it only work for array and hash? It’s just a special rule? Can you use it in other ways? I think for now a bit of repetitiveness is better instead of adding more special rules to the language.
I guess the general rule should just allow using new
on an explicit type unless it’s a union, unless the union is just with Nil.
@a : UInt32? = new # should expand to @a : UInt32 | Nil = UInt32.new
def a(x : Array(String) = new)
record Something, h : Hash(TKey, TValue) = new, i : MyClass = new
Beyond that I guess we’ll have to rely on aliases to factor out verbose type declarations, because : Type = Type.new
is not that bad, but having to go and separately define alias Type = Hash(Key, Value)
is a bit of a speed bump.
The idea sounds great. But new
is a regular method name and would call the new
method in the current scope of available (which would often be the case on class methods).
Hi,
I prefer usage of Alias when I use complexes types.
A type mean something, Tuples(Int32, Int32)
mean nothing for me, but Position
does.
I advise you to do the same
And one step further, just use record
, it’s the same but more explicit.
I always forget about record
.
It’s more explicit and allow specifics methods
Using a dot could work:
x : Array(String) = .new