关于scala * =运算符的返回值

时间:2015-07-22 06:47:05

标签: scala

我正在学习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中,我无法在Long中找到def * =。

5 个答案:

答案 0 :(得分: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
}

但是看到你在这里产生副作用,它并不是真正符合功能性编程的精神。

我更喜欢纯粹的功能:

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

答案 1 :(得分:1)

x *= e构造返回Unit

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

scala> :type t *= 42
Unit

scala> 

答案 2 :(得分:0)

如果没有超载,

t *= …t = t * …的简写 - 一个简单的分配。因为那些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

答案 3 :(得分:0)

作业表达式(使用“=”符号)不返回任何内容,我们可以在Unit中将其称为Scala

*=首先表示*,然后进行分配。因此,您实际上返回Unit,而不是Long。

答案 4 :(得分:0)

当您使用表达式*=时,您正在创建一个副作用,修改左侧的变量,在本例中为t。因为副作用本质上没有返回值,Scala编译器会告诉您类型不匹配,特别是Unit不符合Long

由于t带有您想要的值,product修改tt需要product显式返回return t。将它放在最后一行使它成为返回值(Scala不需要写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返回Query query1 = session.createSQLQuery( //"select transactions.userId from transactions where transactions.id in (select tickets.transactionId from tickets where tickets.validate=:validate and tickets.auctionId in (select id from auctions where sellShare=:sellShare)) group by transactions.userId") "select transactions.userId, auctions.id from auctions inner join (tickets inner join transactions on tickets.transactionId = transactions.id) on auctions.id = tickets.auctionId where auctions.sellShare = :sellShare and tickets.validate=:validate") .addEntity(Test.class).setParameter("sellShare", 1).setParameter("validate", 1); List<Test> tests = query1.list(); 。仔细考虑如何使用递归。