【问题标题】:Crystal Lang: Can't infer the type of instance variable '@hash_value' of RuleCrystal Lang:无法推断 Rule 的实例变量“@hash_value”的类型
【发布时间】:2018-10-31 11:43:41
【问题描述】:

这是我的水晶代码,在 sn-ps 中,但我认为它就在那里:

# spec_helper.rb
def fixtures
  rawhash = JSON.parse(File.read("spec/fixtures/state3.json"))
  rules = rawhash["rules"]
  id = rules.as_h.keys[0]
  hash =  rules[id]
  return id, hash
end

# rule_spec.rb
key, hash = fixtures
rule = Rule.new(key, hash)
rule.array(["name"])[0].must_equal "RpsIphone"

# rule.rb
class Rule  < HueResource

  getter :detail, :on, :name, :lights

  def initialize(key, hashvalue)
    super(key, hashvalue)
    @detail = "#{hashvalue["conditions"].length} conds => #{hashvalue["actions"].length} acts"
    @state.merge! ({"on" => hash_value["status"], "name" => @name, "detail" => @detail})
    gen_reskey("r")
  end
...
end

# hue resource.rb
class HueResource
  def initialize(key, hash_value)
    @hash_value = hash_value.as_h
    @lastupdated = @hash_value["state"]["lastupdated"]
    @detail = hash_value["type"]
    @name = hash_value["name"]
    @state = { "key" => key, "lastupdated" => @lastupdated, "detail" => @detail, "name" => @name}
  end

  def gen_reskey(detail)
    @state.merge!({ "id" => detail + @state["key"]})
  end
end

这是错误:

[Running] crystal "/Users/pitosalas/mydev/crystalplay/spec/rule_spec.cr"
Error in spec/rule_spec.cr:7: instantiating 'Rule.class#new(String, JSON::Any)'

    rule = Rule.new(key, hash)
                [32;1m^~~[0m

in src/rule.cr:7: instantiating 'super(String, JSON::Any)'

    super(key, hashvalue)
    [32;1m^~~~~[0m

in src/hue_resource.cr:3: [1mCan't infer the type of instance variable '@hash_value' of Rule

The type of a instance variable, if not declared explicitly with
`@hash_value : Type`, is inferred from assignments to it across
the whole program.

现在在我看来,在构造函数中,@hash_value 被分配给 hash_value.as_h 所以它会从那里知道类型。

还可以随意指出 Crystal 风格或惯用的 cmets!

【问题讨论】:

    标签: crystal-lang


    【解决方案1】:

    编译器无法从方法调用的返回类型推断 ivar 类型(如hash_value.as_h)。 reference of Type inference 列出了编译器可以推断 ivar 类型的所有规则。

    从方法调用推断类型可能并非不可能,但更复杂。它可能会在某个时候出现在该语言中,但现在您必须使用显式类型注释,例如 @hash_value : Hash(JSON::Any, JSON::Any)

    【讨论】:

    • 谢谢!既然 JSON::Any 看起来很像哈希,我应该把它保留为那种类型吗?
    • 这取决于你想如何使用它。如果您知道 Any 包装了 Hash 并且不能是其他任何东西,那么使用更受限制的类型可能会更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    • 2019-03-20
    • 1970-01-01
    相关资源
    最近更新 更多