2017-01-03 65 views
1

我试图重现Scala中的一个C#语法:对空类型隐式转换

的C#代码:

val myValue = myObject ?? new MyClass(); 

基本上'myvalue的意愿包含“myObject的”,如果它不为空,或者一个'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不为空,但失败了mystring时为空,则返回:

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

1日建议:你应该尝试写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,这是不好的斯卡拉。一旦编译器不知道您的val是什么类型,那么您将从类型系统的全面支持中解脱出来。

+0

感谢您的回答。我喜欢使用的C#语法涉及到一些Scala糟糕的做法...... – reevolt

+0

如果使用通用类型对隐式类进行参数化,它将阻止使用“Any”和类型混合。 – puhlen

+0

@puhlen,如果我们有'class ShortCond [A]'和'def ?? [B]',那么返回类型仍然是A和B的最低上界(LUB),这很可能是' Any'。真正的解决办法是返回'或者[A,B]',但这不是OP要找的。 – jwvh