如何解决Crystal 中的类型规范
我是 Crystal 的新手,我正在尝试将以下程序翻译成 Crystal:
#include <stdio.h>
long rev(long n) {
long m = 0;
while (n > 0) {
m = 10*m + n%10;
n = n/10;
}
return(m);
}
int main() {
for(int n=1; n<=10000000; n++) {
long m = n*rev(n);
if (m==rev(m))
printf("%d\n",n);
}
}
我编写了 Crystal 程序
def rev(n : UInt64) : UInt64
m : UInt64 = 0
while n > 0
m = 10_u64*m + n%10_u64
n = n//10
end
m
end
(1_u64 .. 10_000_000).each { |n|
m = n*rev(n)
if m == rev(m)
print(n,"\n")
end
}
我发现奇怪的是,为了编译,在某些时候我必须指定文字的类型 (n%10_u64
),但在其他时候不需要 (n//10
)。是我遗漏了什么,或者只是 Crystal 在铸造方面不一致?
另外,我想知道,这是对 c 程序的良好翻译还是经验丰富的 Crystal 程序员会怎么做?
解决方法
Crystal 中的默认数字类型是 Int32
。所以如果你不指定类型,就是这样。您的算法在 UInt64
上运行,因此您需要采取一些额外的步骤。
理想情况下,您将只在算法中使用 UInt64
数字,因此所有内容的类型都相同。
但您实际上并不需要,因为这些方法会转换操作数以适应。返回类型始终是第一个操作数的类型。 UInt64#//(Int32)
返回 UInt64
,Int32#*(UInt64)
返回 Int32
。但是,没有像 C 中那样的自动提升。
n // 10
很好,它返回您想要的 n
类型。但是 10 * m
很糟糕,因为它返回 10
的默认类型,即 Int32
并将其分配给 n
会更改其类型。
这乍一看似乎出乎意料,但返回第一种类型的原因是为了允许 x += y
之类的赋值运算符工作,它扩展为 x = x + y
。如果 x + y
返回与 x
不同的类型,这会无意中影响变量的类型。
我的建议是将作为算法一部分的所有数字文字明确键入为 UInt64
以确保它们适合在一起。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。