【问题标题】:Type specification in CrystalCrystal 中的类型规范
【发布时间】:2021-03-10 19:26:21
【问题描述】:

我是 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);
  }
}

我写了水晶程序

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 程序员会怎么做?

【问题讨论】:

    标签: casting crystal-lang


    【解决方案1】:

    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,以确保它们组合在一起。

    【讨论】:

    • 谢谢,我知道它现在是如何工作的了。有趣的是:如果我选择写m*10而不是10*m,我不会遇到任何麻烦。
    猜你喜欢
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-12
    • 2014-10-03
    • 2021-03-18
    相关资源
    最近更新 更多