gpt4 book ai didi

scala - 自定义unapply的值类,会被实例化吗?

转载 作者:行者123 更新时间:2023-12-01 12:31:06 24 4
gpt4 key购买 nike

来自 http://docs.scala-lang.org/overviews/core/value-classes.html

A value class is actually instantiated when:

  • a value class is treated as another type.
  • a value class is assigned to an array.
  • doing runtime type tests, such as pattern matching.

我想知道第三项是否意味着任何模式匹配都会导致实例化,或者它是否特定于 isInstanceOf 检查。

例如,如果我定义一个值类如下:

class Tag(val opening: StartElement) extends AnyVal {
def name: QName = opening.getName
}
object Tag {
def unapply(tag: Tag): Option[String] = {
Some(tag.name.getLocalPart)
}
}

然后像...一样使用它

def matchStack(stack: List[Tag]) = stack match {
case Tag("a") :: Tag("b") :: _ => "ab"
case _ => "something else"
}

是否会实例化任何标签?有没有办法检查(在运行时或编译时)值类是否已实例化?

最佳答案

unapply 方法本身不会装箱 AnyVal。请参阅下面的 java 字节码。请注意,unapply 方法采用 StartElement,而不是 Tag。

但是在列表上下文中使用 AnyVal 肯定会将其装箱。。当与任何 集合(甚至数组)一起使用时,AnyVals 将被装箱。它们不被装箱的唯一情况是当它们是另一个类的直接成员时。

scala> :paste
class StartElement { def getName: String = "foo" }
class Tag(val opening: StartElement) extends AnyVal { def name: String = opening.getName }
object Tag { def unapply(tag: Tag): Option[String] = Some(tag.name) }

scala> :javap -c Tag$
Compiled from "<console>"
public class Tag$ {

public scala.Option<java.lang.String> unapply(StartElement);
Code:
0: new #16 // class scala/Some
3: dup
4: aload_0
5: aload_1
6: invokevirtual #20 // Method name$extension:(LStartElement;)Ljava/lang/String;
9: invokespecial #23 // Method scala/Some."<init>":(Ljava/lang/Object;)V
12: areturn
}

(发布一个不使用诸如 StartElementQName 之类的不安全类型的独立示例将使这种分析更容易)

关于scala - 自定义unapply的值类,会被实例化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34121686/

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