努力理解代码 - 试图返回十进制数字'n'从数字

时间:2016-02-16 03:58:30

标签: swift swift-extensions

我是Swift的新手,正在尝试学习扩展的概念。我在“swift编程语言”中看到了这段代码,它试图从数字的右边返回十进制数字'n'。代码工作正常,但我很难理解代码实际上是如何工作的。

有人可以向我解释一下吗?

extension Int {
    subscript(var digitIndex: Int) -> Int {
        var decimalBase = 1
        while digitIndex > 0 {
            decimalBase *= 10
            --digitIndex
        }
        return (self / decimalBase) % 10
    }
}

746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7
746381295[9]

2 个答案:

答案 0 :(得分:2)

扩展程序通过向现有类型添加功能来工作,但需要注意的是它们无法引入自己的存储。在这种情况下:

/*1*/ extension Int {
/*2*/     subscript(var digitIndex: Int) -> Int {
/*3*/         var decimalBase = 1
/*4*/         while digitIndex > 0 {
/*5*/             decimalBase *= 10
/*6*/             --digitIndex
/*7*/         }
/*8*/         return (self / decimalBase) % 10
          }
      }

第1行将扩展名定义为适用于所有Int类型。

第2行正在为Int设置一个新的下标运算符,这将允许您拥有12345 [4]并生成'某些内容'。第3-8行定义了这一点。

第4-8行中的while将decimalBase乘以10,以获得' digitIndex'倍。有点奇怪的做法,但没关系。结果是如果digitIndex是1,decimalBase是10;如果它是2,则十进制基数为100; 3它的1000;等

胆量在第8行。首先它检索self。由于扩展名适用于Int,因此self将是该整数值。然后它将它除以decimalBase,因为它们都是整数,所以任何小数部分都将丢失。因此,在746381295[2]的情况下,decimalBase将为100,因此您获得7463812.然后它使用'%'得到除法的余数为10.所以7463812除以10是746381,余数为2.所以返回值是2.

希望能够解释它。

预先处理您的问题,在这种情况下我可能会使用for,而不是while

for _ in 0..<digitIndex {
    decimalBase *= 10
}

我并没有过多地考虑上述循环的频率,它可能会经常运行一次或者只运行一次,但是你会明白这一点。

更好的方法是使用“提升力量”。操作员(不确定它叫什么)。

decimalBase = 10 ^^ digitIndex

然后整个定义可以归结为:

return (self / (10 ^^ digitIndex)) % 10

我会留给你决定是否更好。

无论哪种方式,我都不会真正创建这个扩展,我认为它只是为了演示而完成的。

答案 1 :(得分:1)

简单地说,decimalBase计算为1,索引为010,索引为1100索引为21,000,索引为3,依此类推。换句话说,decimalBase最终等于10 ^ digitIndex

例如,请查看digitIndex3的情况。 decimalBase最终会成为1,000,所以:

746381259 / 1000 == 746381

然后:

746381 % 10 == 1

以便您从746381259[3]1的方式。