Scala While循环使用+=时出现类型不匹配错误(Unit/Int)
嘿,刚从Java转Scala的时候我也踩过一模一样的坑,太懂你的困惑了!
问题根源:Scala的+=返回的是Unit,不是你以为的数值
在Java里,像i += 1这种操作会返回更新后的值,但Scala完全不一样——所有带副作用的赋值类操作(包括+=)返回的都是Unit类型(相当于Java里的void,表示“没有有意义的返回值”)。
你之所以在短循环里没遇到问题,大概率是因为短循环里只是单纯执行i += 1这种操作,没有把它的返回值当成Int来用;但在merge函数里,你可能不小心把+=的结果放到了需要Int的场景里(比如赋值给变量、作为循环条件的一部分,或者直接参与计算),这时候编译器就会报错:“找到Unit,需要Int”。
举个错误写法的例子(模拟你可能遇到的场景):
// 错误示范:把+=的返回值当成Int用了 var pos = 0 val result = new Array[Int](10) // 这里试图把pos +=1的结果(Unit)赋值给temp,直接报错 val temp = pos += 1 result(temp) = 5
解决办法:把“赋值操作”和“取值”分开
Scala里的+=只负责修改变量的值,如果你需要更新后的数值,要单独去读取变量,而不是用+=的返回值。
针对merge函数,正确的写法应该是这样的(以合并两个有序数组为例):
def merge(left: Array[Int], right: Array[Int]): Array[Int] = { val merged = new Array[Int](left.length + right.length) var i = 0 // left数组的指针 var j = 0 // right数组的指针 var k = 0 // merged数组的指针 // 同时遍历两个数组 while (i < left.length && j < right.length) { if (left(i) <= right(j)) { merged(k) = left(i) i += 1 // 单纯执行指针移动,不用管返回值 } else { merged(k) = right(j) j += 1 } k += 1 } // 处理left数组剩余元素 while (i < left.length) { merged(k) = left(i) i += 1 k += 1 } // 处理right数组剩余元素 while (j < right.length) { merged(k) = right(j) j += 1 k += 1 } merged }
这里的所有+=都是单独执行的,只是用来更新指针位置,没有把它们的返回值当作Int来使用,自然就不会触发类型不匹配的错误。
额外提示:Scala更推荐函数式写法
虽然用while循环练习是没问题的,但Scala的惯用写法是用函数式的方式处理这类问题,比如用递归或者集合操作符(++、zip等),不过新手阶段先把命令式的坑踩明白,再转函数式会更顺畅~
内容的提问来源于stack exchange,提问作者kapkong
相关产品推荐
相关产品推荐

