Scala Implicit class(在 implicit class 中使用 implicits)- 不是 Int 错误的成员
Scala Implicit class (using implicits inside implicit class) - Not a member of Int error
我想用scala(递归)写一个totient-function。
Euler's totient function counts the positive integers up to a given integer n that are relatively prime to n
我想出了:
object Totient {
implicit class Improvements(val number: Int) {
def totient: Int = {
@tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 1) accumulator
else {
if (number.isDividable(currentN)) helper(currentN - 1, accumulator)
else helper(currentN - 1, accumulator + 1)
}
helper(number, 0)
}
private def isDividable(divisor: Int) = number % divisor == 0
}
}
为了便于阅读,我创建了一个小函数 isDividable
。
我想在我的递归 helper
方法中使用这个函数。
不幸的是我收到以下错误:
Error:(12, 22) value isDividable is not a member of Int
if (number.isDividable(currentN)) helper(currentN - 1, accumulator)
问题:有人可以向我解释一下我做错了什么以及如何解决吗?
编辑:
为了完整起见,我将添加 totient 函数的有效实现:
object Totient {
implicit class Improvements(val number: Int) {
def totient: Int = {
@tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 0) accumulator
else {
if (number.isCoprimeTo(currentN)) helper(currentN - 1, accumulator + 1)
else helper(currentN - 1, accumulator)
}
helper(number, 0)
}
private[Totient] def isCoprimeTo(otherNumber: Int): Boolean = {
gcd(number, otherNumber) == 1
}
private def gcd(firstNumber: Int, secondNumber: Int): Int =
if (secondNumber == 0) firstNumber else gcd(secondNumber, firstNumber % secondNumber)
}
}
private
没有额外信息意味着这里 "accessible only by other methods of Improvements but for the same instance of Improvements".
这意味着您可以调用 isDividable
来获得与您调用 totient/helper 相同的 number
的结果,但它不会成为扩展方法(因为它是在改进之外不可见。
要解决这个问题,您可以更改方法的范围,例如使其对 Totient
:
中定义的所有方法可见
object Totient {
implicit class Improvements(val number: Int) {
def totient: Int = {
@tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 1) accumulator
else {
if (number.isDividable(currentN)) helper(currentN - 1, accumulator)
else helper(currentN - 1, accumulator + 1)
}
helper(number, 0)
}
// notice [Totient] after private
private[Totient] def isDividable(divisor: Int) = number % divisor == 0
}
}
这在我的菊石中编译并有效:
@ import Totient._
import Totient._
@ 12.totient
res2: Int = 6
另一种选择是从 this
而不是 number
调用 isDividable
/isCoprimeTo
。这样,编译器根本不必执行隐式解析来获取方法。使用您的原始代码:
def totient: Int = {
@tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 1) accumulator
else {
if (this.isDividable(currentN)) helper(currentN - 1, accumulator)
else helper(currentN - 1, accumulator + 1)
}
helper(number, 0)
}
(您甚至可以完全省略对 this
的调用,只使用 isDividable(currentN)
,但这会使代码不那么清晰。)
我想用scala(递归)写一个totient-function。
Euler's totient function counts the positive integers up to a given integer n that are relatively prime to n
我想出了:
object Totient {
implicit class Improvements(val number: Int) {
def totient: Int = {
@tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 1) accumulator
else {
if (number.isDividable(currentN)) helper(currentN - 1, accumulator)
else helper(currentN - 1, accumulator + 1)
}
helper(number, 0)
}
private def isDividable(divisor: Int) = number % divisor == 0
}
}
为了便于阅读,我创建了一个小函数 isDividable
。
我想在我的递归 helper
方法中使用这个函数。
不幸的是我收到以下错误:
Error:(12, 22) value isDividable is not a member of Int
if (number.isDividable(currentN)) helper(currentN - 1, accumulator)
问题:有人可以向我解释一下我做错了什么以及如何解决吗?
编辑:
为了完整起见,我将添加 totient 函数的有效实现:
object Totient {
implicit class Improvements(val number: Int) {
def totient: Int = {
@tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 0) accumulator
else {
if (number.isCoprimeTo(currentN)) helper(currentN - 1, accumulator + 1)
else helper(currentN - 1, accumulator)
}
helper(number, 0)
}
private[Totient] def isCoprimeTo(otherNumber: Int): Boolean = {
gcd(number, otherNumber) == 1
}
private def gcd(firstNumber: Int, secondNumber: Int): Int =
if (secondNumber == 0) firstNumber else gcd(secondNumber, firstNumber % secondNumber)
}
}
private
没有额外信息意味着这里 "accessible only by other methods of Improvements but for the same instance of Improvements".
这意味着您可以调用 isDividable
来获得与您调用 totient/helper 相同的 number
的结果,但它不会成为扩展方法(因为它是在改进之外不可见。
要解决这个问题,您可以更改方法的范围,例如使其对 Totient
:
object Totient {
implicit class Improvements(val number: Int) {
def totient: Int = {
@tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 1) accumulator
else {
if (number.isDividable(currentN)) helper(currentN - 1, accumulator)
else helper(currentN - 1, accumulator + 1)
}
helper(number, 0)
}
// notice [Totient] after private
private[Totient] def isDividable(divisor: Int) = number % divisor == 0
}
}
这在我的菊石中编译并有效:
@ import Totient._
import Totient._
@ 12.totient
res2: Int = 6
另一种选择是从 this
而不是 number
调用 isDividable
/isCoprimeTo
。这样,编译器根本不必执行隐式解析来获取方法。使用您的原始代码:
def totient: Int = {
@tailrec
def helper(currentN: Int, accumulator: Int): Int =
if (currentN == 1) accumulator
else {
if (this.isDividable(currentN)) helper(currentN - 1, accumulator)
else helper(currentN - 1, accumulator + 1)
}
helper(number, 0)
}
(您甚至可以完全省略对 this
的调用,只使用 isDividable(currentN)
,但这会使代码不那么清晰。)