具有变量分配的晶体行为

时间:2017-01-10 09:03:20

标签: behavior crystal-lang

我创建了这个类:

1.  class Component
2.
3.    getter :content, :htm_options, :options
3.
4.    @html_options : Hash(Symbol | String, Symbol | String)
5.    @options      : Hash(Symbol | String, Symbol | String)
6.    @content      : String
7.
8.    def initialize(c = nil, o = nil, h = nil, block = nil)
9.      if false #!block.nil?
10.       @html_options = o unless o.nil? 
11.       @options      = c unless c.nil?
12.       context  = eval("self", block.binding)
13.       @content = context.capture(&block)
14.     else
15.       if c.is_a?(Hash)
16.         @html_options = o unless o.nil? 
17.         @options      = c unless c.nil?
18.       else
19.         @html_options = h unless h.nil? 
20.         @options      = o unless o.nil? 
21.         @content      = c unless c.nil? 
22.        end
23.     end
24.   end
25. end  

Component.new("My text")

我有一个错误:

in src/ui_bibz/ui/core/component.cr:11: instance variable '@options' of Component must be Hash(String | Symbol, String | Symbol), not String
@options = c unless c.nil?

我不理解这种行为,因为我没有传递if条件。我想根据几个条件分配@htm_options, @options, @content。 是否可以声明一个已经声明过一次的变量?

2 个答案:

答案 0 :(得分:3)

我担心在检查类型时,编译器有时不够聪明,无法检测哪些路径被采用,哪些路径没有。因此,在第11行中,编译器发现您正在尝试将String分配给先前定义为Hash的变量,并且失败。

至于你的问题,我担心不可能重新声明一个实例变量。如果你确实希望@options同时拥有String或Hash,你可以声明它是Hash和String的联合。

答案 1 :(得分:0)

Crystal是打字的,这是一件好事,但就我而言,我想重新定义我的变量。我的代码就像" link_to"在红宝石。组件必须以不同方式写入。有时,内容将由变量填充,有时通过块填充。 Initialize方法将以不同方式填充。有没有办法通过宏或其他解决方案重新定义变量?

class Component < UiBibz::Ui::Base

  getter :content, :htm_options, :options

  def initialize(c = nil, o = nil, h = nil, block = nil)
    if !block.nil?
      html_opts, opts = o, c
      context  = eval("self", block.binding)
      @content = context.capture(&block)
    else
      if c.is_a?(Hash)
        html_opts, opts = o, c
      else
        html_opts, opts, cont = h, o, c
      end
    end
    @html_options = html_opts || {} of Symbol => Symbol | String
    @options      = opts      || {} of Symbol => Symbol | String
    @content      = content
  end
end 

# 1 way
Component.new("My content", { :option_1 => true }, { :class => "red" })  

# 2 way
Component.new({ :option_1 => true }, { :class => "red" }) do
  "My content"
end         

错误:

in src/ui_bibz/ui/core/component.cr: instance variable '@options' of Component must be Hash(Symbol, String | Symbol), not (Hash(Symbol, String | Symbol) | String)
@options = opts || {} of Symbol => Symbol | String