微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Crystal 中的类型规范

如何解决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) 返回 UInt64Int32#*(UInt64) 返回 Int32。但是,没有像 C 中那样的自动提升。

n // 10 很好,它返回您想要的 n 类型。但是 10 * m 很糟糕,因为它返回 10 的默认类型,即 Int32 并将其分配给 n 会更改其类型。

这乍一看似乎出乎意料,但返回第一种类型的原因是为了允许 x += y 之类的赋值运算符工作,它扩展为 x = x + y。如果 x + y 返回与 x 不同的类型,这会无意中影响变量的类型。

我的建议是将作为算法一部分的所有数字文字明确键入为 UInt64 以确保它们适合在一起。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。