📜  斯卡拉 |封印特质

📅  最后修改于: 2022-05-13 01:55:34.572000             🧑  作者: Mango

斯卡拉 |封印特质

Sealed为我们的应用程序提供了详尽的检查。详尽检查允许检查密封特征的所有成员是否必须在与源文件相同的文件中声明。这意味着编译器预先知道必须包含的所有可能已知的特征成员。因此,这为我们提供了防止代码错误的优势。

句法 :

sealed trait X
class A extends X
class B extends X
class C extends X

详尽检查主要用于scala中的类型/模式匹配。假设我们有一个密封的特征 X 和扩展特征 X 的类。在匹配特征 X 的子类型时,我们必须确保包含所有已知的子类型是必须的。下面的方法会给我们一个警告。虽然我们会得到正确的输出,但这可能会导致我们的应用程序出现意外的运行时崩溃。

Warning: match may not be exhaustive
def obj(item: X) = item match {
   case A => //
   case B => //
}

正确的实施就像-

def obj(item: X) = item match{
   case A => //
   case B => //
   case C => //
   or 
   case _ => //for covering all the remaining cases
}

让我们看一下保存为language.scala的文件中的以下程序:-

例子 :

Scala
// Scala Program that illustrates sealed trait
// language.scala
sealed trait Geeks
{
    val article="not done"
}
 
// Class extends trait
class Scala extends Geeks
{
    override val article = "scala article"
}
 
// Class extends trait
class Java extends Geeks
{
    override val article = "java article"
}
 
// Class extends trait
class Csharp extends Geeks
{
    override val article = "csharp article"
}
 
// Creating object
object GFG
{
    // Main method
    def main(args: Array[String])
    {
        val s = new Scala
        val j = new Java
        val c = new Csharp
        println(checkArticle(s))
        println(checkArticle(j))
        println(checkArticle(c))
    }
     
    // Defined function
    def checkArticle(Article: Geeks): String = Article match
    {
        case s: Scala  => s.article
        case j: Java   => j.article
        case c: Csharp => c.article
        //exclusion of line 45 would lead to warning
    }
}


Scala
// Scala Program that illustrates sealed trait
// By using Enumeration
sealed trait card extends Enumeration
 
// Class extends trait
case object CLUB extends card
 
// Class extends trait
case object HEART extends card
 
// Class extends trait
case object DIAMOND extends card
 
// Class extends trait
case object SPADE extends card
 
// Creating object
object obj1
{  
    // Main method
    def main(args: Array[String])
    {
        val card1 = HEART
        val card2 = CLUB
        val card3 = SPADE
        val card4 = DIAMOND
        println(checkcard(card1))
        println(checkcard(card2))
        println(checkcard(card3))
        println(checkcard(card4))
    }
     
    // Defined function
    def checkcard(x: card): String = x match
    {
         
        case HEART   =>"heart"
        case CLUB    =>"club"
        case SPADE   =>"spade"
        case DIAMOND =>"diamond"
    }
}


输出 :

scala article
java article
csharp article
一些重要的点
  • 特征的子类型是预先知道的——在模式匹配中不包括任何密封类 C 的子类型会给我们警告。这样的警告告诉您,由于某些可能的模式未处理,您的代码可能会产生匹配错误异常的风险。该警告指出了运行时错误的潜在来源,因此它通常是使您的程序正确的一个受欢迎的帮助。
  • 密封特征只能在与子类型相同的源文件中扩展 -在上面的示例中,我们在另一个 scala 文件中有另一个类Python 。从language.scala导入 trait geeks我们会得到如下错误消息。
illegal inheritance from sealed trait bag
import geeks
class python extends geeks{
    val article="python article";
}
  • 密封类也主要用于枚举——防止非法继承并使用所有子类型以避免详尽的匹配警告。
    例子 :

斯卡拉

// Scala Program that illustrates sealed trait
// By using Enumeration
sealed trait card extends Enumeration
 
// Class extends trait
case object CLUB extends card
 
// Class extends trait
case object HEART extends card
 
// Class extends trait
case object DIAMOND extends card
 
// Class extends trait
case object SPADE extends card
 
// Creating object
object obj1
{  
    // Main method
    def main(args: Array[String])
    {
        val card1 = HEART
        val card2 = CLUB
        val card3 = SPADE
        val card4 = DIAMOND
        println(checkcard(card1))
        println(checkcard(card2))
        println(checkcard(card3))
        println(checkcard(card4))
    }
     
    // Defined function
    def checkcard(x: card): String = x match
    {
         
        case HEART   =>"heart"
        case CLUB    =>"club"
        case SPADE   =>"spade"
        case DIAMOND =>"diamond"
    }
}

输出 :

heart
club
spade
diamond