2017-01-03 8 views
1

私はスカラ座でのC#構文を再現しようとしている:暗黙の変換

C#コード:

val myValue = myObject ?? new MyClass(); 

それがnullでない場合は基本的に 'myValue' 意志 'はmyObjectという' が含まれている、またはnullの場合は 'MyClass'の新しいインスタンスです。

これは私が実行しようとしたScalaのコードです:

case class ShortCond(original: Any){ 
    def ??(fallback : Any) { 
    if (original == null) 
     return fallback 
    return original 
    } 
} 
implicit def any2ShortCond(original: Any) = ShortCond(original) 


val myString = null 
val value = myString ?? "myString is null" 

MYSTRINGたときにそれが機能するには、nullではありませんが、のmyStringがnullであるとき、それは返し失敗:

error: value ?? is not a member of Null 
val value = myString ?? "myString is null" 

私は理解してエラーですが、Scalaでこれを達成する方法があるのでしょうか、それとも不可能ですか?

おかげ

+0

Scalaでは、あなたのコードに 'null'を全く使わないよう勧めています。それはあなたが努力すべきことです。 –

+0

これはScalaコードでnullを使うのは悪いことですが、ライブラリメソッド呼び出しでnull値を返すことができます。 – reevolt

+0

あなたはそうです。実際に行うべきことは、できるだけ最下位の第三者のライブラリからの 'null'値を処理し、' Option [T] 'や他のヌル回避値を伝播することです。 –

答えて

5

第一の提案:あなたはScalaのコードを書くときにScalaのイディオムに固執しようとする必要があります。これを行うためのScalaの方法は何かのような...

implicit class ShortCond(original: Any){ 
    def ??(fallback : Any) = 
    Option(original).getOrElse(fallback) 
} 

val str:String = null 
str ?? 34 // res0: Any = 34 
"x" ?? 43 // res1: Any = x 

かもしれません。しかし、これは、コンパイラはそれを解決することを意味し、主にあなたが混合型を返すようにしようとしている理由の数、のために悪い考えですAnyと入力してください。Scalaはうまくありません。コンパイラがどのタイプをあなたのvalであるか分からなければ、あなたはタイプシステムの完全なサポートからあなた自身を取り除いています。

+0

あなたの答えをありがとう。私が使用することに感謝しているC#構文は、Scalaの悪い習慣を含んでいます... – reevolt

+0

暗黙のクラスをジェネリック型でパラメータ化すると、 'Any'と型混合の使用が妨げられます。 – puhlen

+0

@puhlenもし 'class ShortCond [A]'と 'def ?? [B]'を持っていれば、戻り値の型はAとBの最低上限(LUB)になります。任意の。本当の解決策は 'A [A、B] 'を返すことですが、それはOPが探しているものではありません。 – jwvh