Scala while(true) type mismatch? Infinite loop in scala?

后端 未结 6 2044
感情败类
感情败类 2021-02-14 21:01

Why following code

def doSomething() = \"Something\"

var availableRetries: Int = 10

def process(): String = {
  while (true) {
    availableRetries -= 1
    tr         


        
6条回答
  •  一整个雨季
    2021-02-14 21:48

    Unlike C# (and Java and C and C++) which are statement based languages, Scala is an expression based language. That's mostly a big plus in terms of composibility and readability but in this case the difference has bitten you.

    A Scala method implicitly returns the value of the last expression in the method

    scala> def id(x : String) = x
    id: (x: String)String
    
    scala> id("hello")           
    res0: String = hello
    

    In Scala pretty much everything is an expression. Things that look like statements are still expressions that return a value of a type called Unit. The value can be written as ().

    scala> def foo() = while(false){}
    foo: ()Unit
    
    scala> if (foo() == ()) "yes!" else "no"
    res2: java.lang.String = yes!
    

    No compiler for a Turing-equivalent language can detect all non-terminating loops (c.f. Turing halting problem) so most compilers do very little work to detect any. In this case the type of "while(someCondition){...}" is Unit no matter what someCondition is, even if it's the constant true.

    scala> def forever() = while(true){}
    forever: ()Unit
    

    Scala determines that the declared return type (String) isn't compatible with the actual return type (Unit), which is the type of the last expression (while...)

    scala> def wtf() : String = while(true){}
    :5: error: type mismatch;
     found   : Unit
     required: String
           def wtf() : String = while(true){}
    

    Answer: add an exception at the end

    scala> def wtfOk() : String = {
         | while(true){}
         | error("seriously, wtf? how did I get here?")
         | }
    wtfOk: ()String
    

提交回复
热议问题