2015-07-22 27 views
1

我学习Scala的个人兴趣,我通过以下的返回值困惑:关于斯卡拉* =运算符的返回值

var t : Long = 1 
def product(s:String):Long = { 
    if(s.length > 1) t *= product(s.tail) 
    else t *= s.toLong 
} 

这是一个递归函数,但是编译器高大我有两个错误:

<console>:13: error: type mismatch; 
found : Unit 
required: Long 
     if(s.length > 1) t *= product(s.tail) 
         ^
<console>:14: error: type mismatch; 
found : Unit 
required: Long 
     else t *= s.toLong 
      ^

和在scala-doc中,我找不到def * = in Long。

+0

什么是't'?它在哪里定义? – dhg

+0

对不起var t:长= 1 –

回答

2

t *= product(s.tail)t = t * product(s.tail)

如果你想返回的T他值速记,你必须做明确:

var t : Long = 1 
def product(s:String):Long = { 
    if(s.length > 1) t *= product(s.tail) 
    else t *= s.toLong 

    t 
} 

但看到你副作用的这里T,它不是真正在功能编程的精神。

我更喜欢一个纯函数:

def product(s:String, t: Long):Long = { 
    if(s.length > 1) t * product(s.tail, t) 
    else t * s.toLong 
} 
+0

可能有一个很好的理由使用可变变量。没有足够的上下文来说明这一点,国际海事组织。 – ReyCharles

+0

'product'的递归调用在这里不正确,它应该有两个参数,比如'product(s.tail,t)' – GSPdibbler

0

t *= …,如果不超载,为t = t * …的简写 - 一个简单的分配新建分配FY。由于这些have Unit return type而不是产生新的值(Long),您在这里(两次)得到一个类型错误。

改变你的函数下面应该工作:

def product(s:String): Long = { 
    t *= if(s.length > 1) product(s.tail) else s.toLong 
    t 
} 

但是你应该要么改变返回类型Unit,如果你只关心改变t反正副作用:

var t: Long = 1 
def product(s:String): Unit = { 
    t *= if(s.length > 1) product(s.tail) else s.toLong 
} 

或使功能纯粹而不变异变量:

val t: Long = 1 
def product(s:String): Long = 
    t * if(s.length > 1) product(s.tail) else s.toLong 
1

x *= e构建体返回(用 “=” 符号)Unit

scala> var t : Long = 1 
t: Long = 1 

scala> :type t *= 42 
Unit 

scala> 
0

分配表达没有返回,这是我们可以称之为UnitScala

*=意味着*首先,然后进行分配。因此,您实际上返回Unit,而不是长。

0

当您使用表达式*=时,您正在创建一个修改左侧变量的副作用,在此例中为t。由于其本身的副作用没有返回值,因此Scala编译器会告诉您类型不匹配,具体而言,Unit不符合Long

由于t执行所需的值,其中product修改tt需要由product明确地返回。将它放在最后一行使其成为返回值(Scala不需要编写return t,但是您可以;它相当于任何一种方式)。其他已经发布了补丁,但在这样的情况下,可以考虑这样做:

var t : Long = 1 
def product(s:String) = { 
    if(s.length > 1) t *= product(s.tail) 
    else t *= s.toLong 
    t //Made t the return, which is what you want. 
} 

和合作,通过您的定义从那里。这不会编译,但它会向您显示下一步。想想在所有情况下如何使product返回t。仔细想想你如何使用递归。