use java::util::zip::CRC32:from<java>;
my $crc = CRC32.new();
for 'Hello, Java'.encode('utf-8') {
$crc.'method/update/(B)V'($_);
}
say $crc.getValue();
遗憾的是,这不起作用
Method 'method/update/(B)V' not found for invocant of class 'java.util.zip.CRC32'
此代码可从以下链接获得。这是我能找到的唯一例子
结合下面的你的答案清理部分中解释的代码清理与Pepe Schwarz在下面的期望警报部分中提到的改进,我们得到:
use java::util::zip::CRC32:from<Java>;
my $crc = CRC32.new();
for 'Hello, Java'.encode('utf-8').list {
$crc.update($_);
}
say $crc.getValue();
use v6;
use java::util::zip::CRC32:from<Java>;
my $crc = CRC32.new();
for 'Hello, Java'.encode('utf-8').list { # Appended `.list`
$crc.'method/update/(I)V'($_);
}
say $crc.getValue();
一个重要的改变位是附加的.list
。
'Hello, Java'.encode('utf-8')
片段返回一个对象,一个utf8
。该对象只返回一个值(本身)到qazxswpoi语句。所以for
只迭代一次,将对象传递给代码块,其中包含for
线。
如果update
行是update
,那么迭代一次就有意义了,.'method/update/([B)V'
映射到需要8位整数缓冲区的Java方法,这基本上就是Perl 6 utf8
。然而,这将需要一些支持Perl 6代码(可能在核心编译器中)将Perl 6 utf8
编组(自动转换)为Java buf[]
,如果该代码曾经存在/工作,那么当我使用最新的Rakudo。
但如果一个人如上所示附加一个明智的.list
并更改代码块以匹配,那么事情就会成功。
首先,.list
导致for
语句迭代一系列整数。
其次,和你一样,我调用了Java方法的整数arg版本(.'method/update/(I)V'
)而不是原始的缓冲区arg版本,然后代码正常工作。 (这意味着从Perl 6 utf8
对象返回的无符号8位整数的二进制表示已经完全是Java方法所期望的,或者是为您自动编组的。)
另一个必要的变化是from<java>
需要在下面的评论中使用from<Java>
- 谢谢。
截至2015年1月:
负责Java互操作的这个区域的代码可以在类org.perl6.nqp.runtime.BootJavaInterop
中找到。它表明重载方法由字符串method/<name>/<descriptor>
标识。描述符在函数org.objectweb.asm.Type#getMethodDescriptor
中计算。这个罐子可以通过http://mvnrepository.com/artifact/asm/asm的maven获得。
import java.util.zip.CRC32
import org.objectweb.asm.Type
object MethodSignatures {
def printSignature(cls: Class[_], method: String, params: Class[_]): Unit = {
val m = cls.getMethod(method, params)
val d = Type.getMethodDescriptor(m)
println(m)
println(s"\t$d")
}
def main(args: Array[String]) {
val cls = classOf[CRC32]
# see https://docs.oracle.com/javase/8/docs/api/java/util/zip/CRC32.html
val ab = classOf[Array[Byte]]
val i = classOf[Int]
printSignature(cls, "update", ab)
printSignature(cls, "update", i)
}
}
这打印
public void java.util.zip.CRC32.update(byte[])
([B)V
public void java.util.zip.CRC32.update(int)
(I)V
因为我想调用这个重载方法的update(int)变体,所以正确的方法调用(在示例程序的第5行)是
$crc.'method/update/(I)V'($_);
这与崩溃
This representation can not unbox to a native int
最后,由于某种原因,我不明白,改变相同的行
$crc.'method/update/(I)V'($_.Int);
修复,示例运行正常。
代码的最终版本是
use v6;
use java::util::zip::CRC32:from<java>;
my $crc = CRC32.new();
for 'Hello, Java'.encode('utf-8') {
$crc.'method/update/(I)V'($_.Int);
}
say $crc.getValue();
我在Perl 6.c上进行了以下修改(2018年1月4日):
use v6;
use java::util::zip::CRC32:from<JavaRuntime>;
my $crc = CRC32.new();
for 'Hello, Java'.encode('utf-8').list {
$crc.update($_);
}
say $crc.getValue();
导致:
% perl6-j --version
This is Rakudo version 2017.12-79-g6f36b02 built on JVM
implementing Perl 6.c.
% perl6-j crcjava.p6
1072431491