class Hello
def initialize()
end
def go(name : Int32|String = 32)
name = "" if name.is_a?(Int32)
@name = name
end
end
p = Hello.new
p.go()
then build
$ crystal build tmp6.cr
got this weird error:
Showing last frame. Use --error-trace for full trace.
In tmp6.cr:7:2
7 | @name = name
^----
Error: can't infer the type of instance variable '@name' of Hello
The type of a instance variable, if not declared explicitly with
`@name : Type`, is inferred from assignments to it across
the whole program.
he assignments must look like this:
1. `@name = 1` (or other literals), inferred to the literal's type
2. `@name = Type.new`, type is inferred to be Type
3. `@name = Type.method`, where `method` has a return type
annotation, type is inferred from it
4. `@name = arg`, with 'arg' being a method argument with a
type restriction 'Type', type is inferred to be Type
5. `@name = arg`, with 'arg' being a method argument with a
default value, type is inferred using rules 1, 2 and 3 from it
6. `@name = uninitialized Type`, type is inferred to be Type
7. `@name = LibSome.func`, and `LibSome` is a `lib`, type
is inferred from that fun.
8. `LibSome.func(out @name)`, and `LibSome` is a `lib`, type
is inferred from that fun argument.
Other assignments have no effect on its type.
can't infer the type of instance variable '@name' of Hello
That’s the line that prevents your code from working. Perhaps you should provide a default value for @name:
class Hello
def initialize
@name = "" # or outside #initialize
end
def go(name : Int32 | String = 32)
name = "" if name.is_a?(Int32)
@name = name
end
end
That way the compiler knows what type @name is supposed to be from the get-go.
yes, it works! or use property name : String|Int32 = 3 also works~
It seems @ variable in class should be defined in initialize or property, I got it~
Thanks~
class Hello
alias KK = Int32|Int64|Array(String)
property name2 : KK = 32
def initialize()
end
def go()
@name2 = Array(String).new if @name2.is_a?(Int32)
end
end
p = Hello.new
p.go()
that works, but when I tried this:
class Hello
alias KK = Int32|Int64|Array(String)
property name2 : KK = 32
def initialize()
end
def go()
puts @name2 > 1 if @name2.is_a?(Int32)
end
end
p = Hello.new
p.go()
got error:
In tmp6.cr:8:17
8 | puts @name2 > 1 if @name2.is_a?(Int32)
^
Error: no overload matches 'Array(String)#>' with type Int32
Overloads are:
- Comparable(T)#>(other : T)
Since @name2 can be any type in Int32|Int64|Array(String), this error is catching that there isn’t a method defined that allows you to compare an Array(String) with an Int32.