我是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]
答案 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
,索引为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
的方式。