2017-01-10 66 views
2

水晶行爲,我創建這個類:與變量assignement

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。 是否可以聲明一個已經聲明過的變量?

回答

3

恐怕在檢查類型時,編譯器有時不夠聰明,無法檢測哪些路徑被採用,哪些不是。因此,在第11行中,編譯器發現您正在嘗試將一個String分配給之前定義爲Hash的變量,並且失敗。

至於你的問題,恐怕不可能重新聲明一個實例變量。如果你想要@options同時保存一個字符串或哈希,你可以聲明它是一個哈希和字符串的聯合。

+0

這很煩人:(謝謝 – Thooams

+0

因爲後,我有一個哈希合併@options的方法,但編譯器提醒我有一個錯誤:'找不到重載對於這些類型:Hash(Symbol,Symbol)#merge(other:String)'。這是正常的,因爲我定義了@options就像一個哈希和字符串的聯合。沒有解決方案!! :( – Thooams

+1

總有一個解決方案或破解會工作,但Crystal是靜態類型的,使用完全不同類型的工會通常最終會非常煩人。也許你可以重新思考你的API,所以選項總是一個例如'哈希(字符串,字符串)'? –

0

水晶是打字的,這是一件好事,但對我而言,我想重新定義我的變量。我的代碼像ruby中的「link_to」一樣工作。組件必須以不同的方式寫入。有時候,內容會被變量填充,有時會被塊填充。初始化方法將以不同的方式填充。有一種方法可以通過宏或其他解決方案重新定義變量?

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 
+0

有人嗎?請:( – Thooams

+0

我找到了我的答案!https://blog.codeship.com/crystal-from-a-rubyists-perspective/ 我必須重寫初始化方法。 – Thooams