努力理解代码 - 它试图 return 小数位 'n' 从数字的右边开始
Struggling to understand the code - which tries to return the decimal digit 'n' places in from the right of the number
我是 Swift 的新手,正在尝试学习扩展的概念。我在 "the swift programming language" 中看到这段代码,它试图 return 小数位 '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]
简单的说,decimalBase
被计算为1
索引为0
,10
索引为1
,100
索引为 2
,1,000
索引为 3
,依此类推。换句话说,decimalBase
最终等于 10 ^ digitIndex
.
所以看看 digitIndex
是 3
的情况。 decimalBase
最终会变成 1,000
,所以:
746381259 / 1000 == 746381
然后:
746381 % 10 == 1
这就是您从 746381259[3]
到 1
的方式。
扩展通过向现有类型添加功能来工作,但需要注意的是它们不能引入自己的存储。在这种情况下:
/*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] 并产生 'something'。第 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
}
我没有想太多关于上述循环的频率,它可能 运行 一次到经常或一次太少,但你明白了。
更好的方法是使用 'raising to the power' 运算符(不太确定它叫什么)。
decimalBase = 10 ^^ digitIndex
那么整个定义可以归结为:
return (self / (10 ^^ digitIndex)) % 10
我会留给你来决定这是否更好。
不管怎样,我都不会真正创建这个扩展,我假设它只是为了演示而创建的。
我是 Swift 的新手,正在尝试学习扩展的概念。我在 "the swift programming language" 中看到这段代码,它试图 return 小数位 '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]
简单的说,decimalBase
被计算为1
索引为0
,10
索引为1
,100
索引为 2
,1,000
索引为 3
,依此类推。换句话说,decimalBase
最终等于 10 ^ digitIndex
.
所以看看 digitIndex
是 3
的情况。 decimalBase
最终会变成 1,000
,所以:
746381259 / 1000 == 746381
然后:
746381 % 10 == 1
这就是您从 746381259[3]
到 1
的方式。
扩展通过向现有类型添加功能来工作,但需要注意的是它们不能引入自己的存储。在这种情况下:
/*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] 并产生 'something'。第 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
}
我没有想太多关于上述循环的频率,它可能 运行 一次到经常或一次太少,但你明白了。
更好的方法是使用 'raising to the power' 运算符(不太确定它叫什么)。
decimalBase = 10 ^^ digitIndex
那么整个定义可以归结为:
return (self / (10 ^^ digitIndex)) % 10
我会留给你来决定这是否更好。
不管怎样,我都不会真正创建这个扩展,我假设它只是为了演示而创建的。