我正在学习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 * =。
答案 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
修改t
,t
需要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();
。仔细考虑如何使用递归。