Scala中泛型整数的类型不匹配

Scala中泛型整数的类型不匹配,scala,generics,encoding,type-conversion,Scala,Generics,Encoding,Type Conversion,我正在尝试用Scala编写一个解码器 (Base64 VLQ编码有符号整数序列。该编码对编码的整数范围没有限制。) 对于我当前的用例,我知道Seq[Int]就足够了。当然,我想这样做,这样我就可以解码到Seq[Long],或者Seq[biginger],甚至类似于Seq[Short] 算法完全相同,只是类型不同 非专利药拯救!(至少我是这么想的。) 我可以看到问题:0、value和newValue都是Int类型 我能做些什么来解决这个问题 FYI,这就是我在C++中如何做同样的事情,只有几

我正在尝试用Scala编写一个解码器

(Base64 VLQ编码有符号整数序列。该编码对编码的整数范围没有限制。)

对于我当前的用例,我知道
Seq[Int]
就足够了。当然,我想这样做,这样我就可以解码到
Seq[Long]
,或者
Seq[biginger]
,甚至类似于
Seq[Short]

算法完全相同,只是类型不同

非专利药拯救!(至少我是这么想的。)


我可以看到问题:
0
value
newValue
都是
Int
类型

我能做些什么来解决这个问题


FYI,这就是我在C++中如何做同样的事情,只有几行代码。

#include <vector>

template<typename T>
std::vector<T> decode(std::vector<char> bytes) {
    char continuationMask = 1 << 5;
    char signMask = 1;
    vector<T> result;
    int n(0);
    T value(0);
    for(auto it = bytes.begin(); it != bytes.end(); it++) {
        if(*it & continuationMask) {
            value += (*it & ~continuationMask) << 5 * n;
            n++;
        } else {
            value += (*it / 2 & ~continuationMask) << 5 * n;
            result.push_back(*it & signMask ? -value : value);
            value = 0;
            n = 0;
        }
    }
    return result;
}
#包括
样板
std::矢量解码(std::矢量字节){

char continuationMask=1这并不能解决您的问题,但希望它能帮助您编写一个通用的解决方案。请查看和提供的操作。问题在于位操作。如果您选择这种方式,则必须使用Integral和IntegrationOps支持的操作重写它们。祝您好运

object Base64Vlq {
  val continuationMask = (1 << 5).toByte
  val signMask = 1.toByte

  def decode[T](bytes: Seq[Byte])(implicit integral: Integral[T]): Seq[T] = {
    import integral._

    val result = scala.collection.mutable.ListBuffer[T]()
    bytes.foldLeft((integral.zero, integral.zero)) { (arg, byte) =>
      val (value, n) = arg
      if((byte & continuationMask) == integral.zero) {
        // Just a meaningless example calculation:
        result += integral.fromInt(2) + (value * n)

        (integral.zero, integral.zero)
      } else {
        // Just a meaningless example calculation:
        (value + integral.fromInt(3) * n, n + integral.fromInt(1))
      }
    }
    result
  }
}
objectbase64vlq{
val continuationMask=(1)
val(值,n)=arg
if((字节和连续掩码)=整数.0){
//只是一个毫无意义的计算示例:
结果+=整数。fromInt(2)+(值*n)
(整数。零,整数。零)
}否则{
//只是一个毫无意义的计算示例:
(值+整数.fromInt(3)*n,n+整数.fromInt(1))
}
}
后果
}
}

这并不能解决您的问题,但希望它能帮助您编写一个通用的解决方案。请查看和提供的操作。问题在于位操作。如果您选择这种方式,则必须使用Integral和IntegralOps支持的操作重写它们。祝您好运

object Base64Vlq {
  val continuationMask = (1 << 5).toByte
  val signMask = 1.toByte

  def decode[T](bytes: Seq[Byte])(implicit integral: Integral[T]): Seq[T] = {
    import integral._

    val result = scala.collection.mutable.ListBuffer[T]()
    bytes.foldLeft((integral.zero, integral.zero)) { (arg, byte) =>
      val (value, n) = arg
      if((byte & continuationMask) == integral.zero) {
        // Just a meaningless example calculation:
        result += integral.fromInt(2) + (value * n)

        (integral.zero, integral.zero)
      } else {
        // Just a meaningless example calculation:
        (value + integral.fromInt(3) * n, n + integral.fromInt(1))
      }
    }
    result
  }
}
objectbase64vlq{
val continuationMask=(1)
val(值,n)=arg
if((字节和连续掩码)=整数.0){
//只是一个毫无意义的计算示例:
结果+=整数。fromInt(2)+(值*n)
(整数。零,整数。零)
}否则{
//只是一个毫无意义的计算示例:
(值+整数.fromInt(3)*n,n+整数.fromInt(1))
}
}
后果
}
}

边界
T边界
T你能(1)解释为什么必须有一个
Integral[T]
的实例,以及(2)如何使用它吗?
Base64Vlq.decode(Seq[Byte]())
给出
错误:不明确的隐式值:object scala.math.Numeric.biginitsintegral类型的object Numeric中的object biginitsintegral和object scala.math.Numeric.initsintegral类型的object Numeric中的object initsintegral与预期的类型Integral[T]匹配
.Oh duh…#2应该是显而易见的。谢谢!请注意,有一个导入可以用来避免
Integral
类型类的笨拙语法,并使用普通的中缀数学运算符(同时仍然使用类型类来实现它们)。您能否(1)详细说明为什么必须有
Integral[T]
的实例,以及(2)如何使用此选项?
Base64Vlq.decode(Seq[Byte]())
给出
错误:不明确的隐式值:object scala.math.Numeric.biginistingegral类型的object Numeric中的object biginistingegral和object scala.math.Numeric.initingegral类型的object Numeric中的object initingegral匹配预期的类型Integral[T]
.Oh duh…#2应该是显而易见的。谢谢!请注意,有一个导入可以用来避免
Integral
type类的笨拙语法,并使用普通的中缀数学运算符(同时仍然使用type类来实现它们)。任何“泛型”Scala中的解决方案会很慢。您可能会尝试使用专门化来获得更好的性能,但我不确定这会让您走多远。如果您需要速度,而且这看起来是需要的,请保持非通用性。@DanielC.Sobral,是的,Java泛型很慢。Alexey的解决方案,即使有专门化,性能仍然会受到影响。任何“通用性”Scala中的解决方案会很慢。您可能会尝试使用专门化来获得更好的性能,但我不确定这会让您走多远。如果您需要速度,而且这看起来是需要的,请保持非通用性。@DanielC.Sobral,是的,Java泛型很慢。Alexey的解决方案,即使有专门化,性能仍然会受到影响。
object Base64Vlq {
  val continuationMask = (1 << 5).toByte
  val signMask = 1.toByte

  def decode[T](bytes: Seq[Byte])(implicit integral: Integral[T]): Seq[T] = {
    import integral._

    val result = scala.collection.mutable.ListBuffer[T]()
    bytes.foldLeft((integral.zero, integral.zero)) { (arg, byte) =>
      val (value, n) = arg
      if((byte & continuationMask) == integral.zero) {
        // Just a meaningless example calculation:
        result += integral.fromInt(2) + (value * n)

        (integral.zero, integral.zero)
      } else {
        // Just a meaningless example calculation:
        (value + integral.fromInt(3) * n, n + integral.fromInt(1))
      }
    }
    result
  }
}
object Base64Vlq {
  val continuationMask = (1 << 5).toByte
  val signMask = 1.toByte

  def decode[T](bytes: Seq[Byte])(implicit ev: Integral[T]): Seq[T] = {
    val result = scala.collection.mutable.ListBuffer[T]()
    val tZero = ev.zero
    bytes.foldLeft((tZero, 0)) { (arg, byte) =>
      val (value, n) = arg
      if((byte & continuationMask) == 0) {
        val newValue = ev.plus(value, ev.fromInt((byte / 2 & ~continuationMask) << 5 * n))
        result += (if((byte & signMask) == 0) { newValue } else { ev.negate(newValue) })
        (tZero, 0)
      } else {
        (ev.plus(value, ev.fromInt((byte & ~continuationMask).toInt << 5 * n)), n + 1)
      }
    }
    result
  }
}