3

次のコードはうまく機能し、「5.0」を出力します

$x : Float64
$y : Float64
$x = 3.0_f64
$y = 2.0_f64
puts $x + $y

ここで、「nil」をサポートするようにコードを変更します。

$x : Float64?
$y : Float64?
$x = 3.0_f64
$y = 2.0_f64
puts $x + $y if !$x.nil? && !$y.nil?

ただし、このコードは次のエラー メッセージを報告します。

タイプ (Float64 | Nil) の 'Float64#+' に一致するオーバーロードはありません
オーバーロードは次のとおりです。
 - Float64#+(その他: Int8)
 - Float64#+(その他: Int16)
 - Float64#+(その他: Int32)
 - Float64#+(その他: Int64)
 - Float64#+(その他: UInt8)
 - Float64#+(その他: UInt16)
 - Float64#+(その他: UInt32)
 - Float64#+(その他: UInt64)
 - Float64#+(その他: Float32)
 - Float64#+(その他: Float64)
 - 数字#+()
これらの型のオーバーロードが見つかりませんでした:
 - Float64#+(なし)

    put $x + $y if !$x.nil? && !$y.nil?

$x または $y が nil の場合はメソッド "#+()" の呼び出しを停止し、両方が Float64 の場合は計算結果を出力したいと考えています。

この状況のベストプラクティスは何ですか?


上記のコードでは、この質問のコードを簡略化しました。その結果、思わず質問の意味が変わってしまいました.. 実際に質問したかったのは以下のコードです。

class Xyz
  property a, b
  @a : Float64?
  @b : Float64?

  def initialize
    @a = nil
    @b = nil
  end

  def do_calc
    if !@a.nil? && !@b.nil?
      puts @a + @b
    else
      puts "We can't calculate because '@a or @b has nil."
    end
  end
end

x = Xyz.new
x.a = 3.0_f64
x.b = 2.0_f64
x.do_calc

このコードは、次のエラーを報告します。

「Xyz#do_calc()」のインスタンス化

x.do_calc
  ^~~~~~~

in ./a.cr:15: タイプ (Float64 | Nil) の 'Float64#+' に一致するオーバーロードはありません
オーバーロードは次のとおりです。
 - Float64#+(その他: Int8)
 - Float64#+(その他: Int16)
 - Float64#+(その他: Int32)
 - Float64#+(その他: Int64)
 - Float64#+(その他: UInt8)
 - Float64#+(その他: UInt16)
 - Float64#+(その他: UInt32)
 - Float64#+(その他: UInt64)
 - Float64#+(その他: Float32)
 - Float64#+(その他: Float64)
 - 数字#+()
これらの型のオーバーロードが見つかりませんでした:
 - Float64#+(なし)

      @a + @b を置く

このエラーを回避するにはどうすればよいですか?

4

2 に答える 2

4

if と nil の確認に関するドキュメントを必ずお読みください: https://crystal-lang.org/docs/syntax_and_semantics/if_var.htmlおよびhttps://crystal-lang.org/docs/syntax_and_semantics/if_var_nil.html

これはローカル変数にのみ適用されるため、最初に値をローカル変数に割り当てる必要があります。

補足として、Crystal 0.19.0 の時点で、グローバル変数は言語に存在しなくなりました。

于 2016-09-07T15:17:37.847 に答える