gpt4 book ai didi

arrays - 在 Scala 中组合数组时的有趣发现

转载 作者:行者123 更新时间:2023-12-04 01:07:14 25 4
gpt4 key购买 nike

我在理解 Scala 中的数组组合时遇到了一些麻烦。

以下工作正常:

scala> Array('0', '1', '2') ++ Array('A', 'B', 'C')
res0: Array[Char] = Array(0, 1, 2, A, B, C)

但这个没有:
scala> ('0' to '9').toArray ++ ('A' to 'Z').toArray
<console>:8: error: polymorphic expression cannot be instantiated to expected type;
found : [B >: Char]Array[B]
required: scala.collection.GenTraversableOnce[?]
('0' to '9').toArray ++ ('A' to 'Z').toArray
^

此外,以下似乎有效:
scala> ('0' to '9').toArray
res1: Array[Char] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> ('A' to 'Z').toArray
res2: Array[Char] = Array(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z)

scala> res1 ++ res2
res3: Array[Char] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z)

我发现的另一个有趣的地方:
scala> (('0' to '9').toArray) ++ (('A' to 'Z').toArray[Char])
res4: Array[Char] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z)

我无法真正解释这一点 - 我错过了什么吗?

最佳答案

++方法在 ArrayOps 中定义:

def ++[B](that: GenTraversableOnce[B]): Array[B]

Returns a new mutable indexed sequence containing the elements from the left hand operand followed by the elements from the right hand operand. The element type of the mutable indexed sequence is the most specific superclass encompassing the element types of the two operands.



推断存储结果的 Array 的类型。
('0' to '9').toArray ++ ('A' to 'Z').toArray
('0' to '9').toArray效果很好,我们得到了一个 Array[Char] .
8: materializing requested scala.reflect.type.ClassTag[Char] using `package`
.this.materializeClassTag[Char]...

根据我们接受的方法定义 GenTraversableOnce[B] .在我们的例子中,我们接受 GenTraversableOnce[Char] .

如果我们使用 -Ytyper-debug 重新运行 scala选项,我们可以看到类型推断在起作用。
//it tries to find the type of arg0
typing '0'.to('1').toArray.$plus$plus('A'.to('B').toArray): pt = ?: undetparams=, implicitsEnabled=true, enrichmentEnabled=true, mode=EXPRmode, silent=false, context.owner=value res1
typing '0'.to('1').toArray.$plus$plus: pt = ?: undetparams=, implicitsEnabled=true, enrichmentEnabled=true, mode=EXPRmode BYVALmode POLYmode FUNmode, silent=true, context.owner=value res1
typing '0'.to('1').toArray: pt = ?: undetparams=, implicitsEnabled=true, enrichmentEnabled=true, mode=EXPRmode POLYmode QUALmode, silent=true, context.owner=value res1
typing '0'.to('1'): pt = ?: undetparams=, implicitsEnabled=true, enrichmentEnabled=true, mode=EXPRmode POLYmode QUALmode, silent=true, context.owner=value res1
typing '0'.to: pt = ?: undetparams=, implicitsEnabled=true, enrichmentEnabled=true, mode=EXPRmode BYVALmode POLYmode FUNmode, silent=true, context.owner=value res1
typing '0': pt = ?: undetparams=, implicitsEnabled=true, enrichmentEnabled=true, mode=EXPRmode POLYmode QUALmode, silent=true, context.owner=value res1
typed '0': Char('0')
adapted '0': Char to ?,
//It succeeds.
//Now it infers a scala type
infer implicit view {
tree '0'
pt Char('0') => ?{def to: ?}

}
new ImplicitSearch(floatWrapper) {...}
...
new ImplicitSearch(charWrapper) {...}

}

//The interesting bit...
typedImplicit1 charWrapper, pt=Char('0') => ?{def to: ?}, from implicit charWrapper:(c: Char)scala.runtime.RichChar
Implicit search yielded: SearchResult(scala.this.Predef.charWrapper, )
typed scala.this.Predef.charWrapper('0').to('1'): scala.collection.immutable.NumericRange.Inclusive[Char]
adapted scala.this.Predef.charWrapper('0').to('1'): scala.collection.immutable.NumericRange.Inclusive[Char] to ?,
typed scala.this.Predef.charWrapper('0').to('1').toArray: [B >: Char](implicit evidence$1: scala.reflect.ClassTag[B])Array[B]

//repeat the process
Infer implicit {
tree scala.this.Predef.charWrapper('0').to('1').toArray[Char]
pt scala.reflect.ClassTag[Char]
undetparams
}

推理过程重复进行,并从对该类型的方法调用中进一步推断出类型,即 ++ . ('0' to '1').toArray ++的类型终于解析为 ArrayOps .
 Implicit search yielded: SearchResult(scala.this.Predef.charArrayOps, )

adapted this.charArrayOps(charWrapper('0').to('1').toArray[Char](ClassTag.Char)).++: [B >: Char, That](that: scala.collection.GenTraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[Array[Char],B,That])That to ?, undetparams=type B, type That

Scala 然后输入我们的第二个参数...
 typed scala.this.Predef.charWrapper('A').to('B'): scala.collection.immutable.NumericRange.Inclusive[Char]
adapted scala.this.Predef.charWrapper('A').to('B'): scala.collection.immutable.NumericRange.Inclusive[Char] to ?,
typed scala.this.Predef.charWrapper('A').to('B').toArray: [B >: Char](implicit evidence$1: scala.reflect.ClassTag[B])Array[B]

最后,我们看看我们的 Array[B]GenTraversableOnce特征。
 infer implicit view {
tree <empty>
pt Array[?B] => scala.collection.GenTraversableOnce[?]
undetparams
}

当然,它没有,我们得到:
typing private[this] val res1: <error> = '0'.to('1').toArray.$plus$plus('A'.to('B').toArray): pt = ?: undetparams=, implicitsEnabled=true, enrichmentEnabled=true, mode=EXPRmode BYVALmode, silent=false, context.owner=object $iw
typed private[this] val res1: <error> = scala.this.Predef.charArrayOps(scala.this.Predef.charWrapper('0').to('1').toArray[Char](ClassTag.Char)).++[B, That]('A'.to('B').toArray): <notype>

https://stackoverflow.com/a/6124177/2823715有关原因的信息。

解决方法是使用 ++ :
def ++:[B >: T, That](that: collection.Traversable[B])(implicit bf: CanBuildFrom[Array[T], B, That]): That

It differs from ++ in that the right operand determines the type of the resulting collection rather than the left one. Mnemonic: the COLon is on the side of the new COLlection type.



它还使 ArrayOps来自 Arrays ,这就是您所需要的。

我们的输入调试输出证实了这一点:
typing {
<synthetic> val x$1 = '0'.to('1').toArray;
'A'.to('B').toArray.$plus$plus$colon(x$1)
}:
...
typed scala.this.Predef.charWrapper('0').to('1').toArray: [B >: Char](implicit evidence$1: scala.reflect.ClassTag[B])Array[B]
...
typing scala.this.Predef.charArrayOps(scala.this.Predef.charWrapper('A').to('B').toArray(ClassTag.Char())).++:(scala.this.Predef.wrapCharArray(x$1), scala.this.Array.canBuildFrom(ClassTag.Char())): pt = Array[Char]: undetparams=, implicitsEnabled=false, enrichmentEnabled=false, mode=EXPRmode BYVALmode, silent=false, context.owner=value res2
...
<synthetic> val x$1: Array[Char] = new runtime.RichChar(scala.this.Predef.charWrapper('0')).to(scala.Char.box('1')).toArray(ClassTag.Char()).$asInstanceOf[Array[Char]]();
scala.this.Predef.charArrayOps(new runtime.RichChar(scala.this.Predef.charWrapper('A')).to(scala.Char.box('B')).toArray(ClassTag.Char()).$asInstanceOf[Array[Char]]()).++:(scala.this.Predef.wrapCharArray(x$1), scala.this.Array.canBuildFrom(ClassTag.Char())).$asInstanceOf[Array[Char]]()

关于arrays - 在 Scala 中组合数组时的有趣发现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20097507/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com