How to specify paramater of array of type in "Initialize"


#1

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)


#2

def initialize(@contents : Array(String), @line : Int32, @position : Int32)


#3

Well that was easy! Thank you very much Blacksmoke16


#4
[] of T

Creates an empty array for values with type T.

Array(T)

Is the type of an array for values with type T


#5

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?


#6

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.


#7

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.


#8

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.


#9

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).


#10

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 :slight_smile:


#11

And one step further, just use record, it’s the same but more explicit.


#12

I always forget about record.

It’s more explicit and allow specifics methods :heart:


#13

Using a dot could work:

x : Array(String) = .new