0. Prefácio
A verificação de tipo e a conversão de tipo têm implementações correspondentes em cada idioma, como Java
na instanceof
e isInstance
na linguagem Scala, mas em comparação com outras linguagens, a Scala
fim de simplificar o desenvolvimento, uma correspondência de padrões poderosa é produzida. O princípio Java
é switch-case
muito semelhante ao do chinês. Mas sua capacidade de correspondência é mais forte, não só pode corresponder valores, tipos de correspondência, mas também correspondência de classe, mas também correspondência de classe de prefixo, e um Spark
grande número de correspondência de padrões é usado no código-fonte, e o outro é a conversão implícita. Em outro artigo O artigo explica que este artigo começa com verificação de tipo e conversão de tipo e apresenta Scala
várias correspondências de padrões comuns e seu uso.
1. Verificação de tipo
Para testar se um objeto pertence a uma determinada classe, você pode usar isInstanceOf
métodos. Se o teste for bem-sucedido, o asInstanceOf
método pode ser usado para conversão de tipo.
if(p.isInstanceOf[Employee]){
//s的类型转换为Employee
val s = p.asInstanceOf[Employee]
}
A conversão de tipo tem principalmente os seguintes pontos a serem observados:
Se p apontar para um
Employee
objeto da classe e suas subclasses, elep.isInstanceOf[Employee]
terá sucesso.Se p for nulo, ele
p.isInstanceOf[Employee]
retornará falso ep.asInstanceOf[Employee]
nulo.Se p não for a
Employee
, elep.asInstanceOf[Employee]
lançará uma exceção.Se você quiser testar se p aponta para um
Employee
objeto, mas não para sua subclasse, você pode usar: Oif(p.getClass == classOf[Employee])
classOf
método é definido noscala.Predef
objeto, portanto, será introduzido automaticamente. No entanto, em comparação com a verificação de tipo e conversão, a correspondência de padrões geralmente é a melhor escolha.
p match{
//将s作为Employee处理
case s: Employee => ...
//p不是Employee的情况
case _ => ....
}
2. Correspondência de padrões
Em resumo, a correspondência de padrões no Scala suporta os seguintes tipos de correspondência: correspondência de valor, correspondência de tipo, elementos de conjunto, correspondência de tupla, correspondência com valor ou sem valor, vamos dar uma olhada em como esses tipos de correspondência são usados a partir do ponto de código de visualização. Primeiro, o padrão A estrutura de sintaxe correspondente é a seguinte:
变量 match {
case xx => 代码
}
E as Java
diferenças não precisam ser especificadas break
, ou seja, break
o efeito de usar um marcador _
para representar um valor padrão, adição match
e if
como o valor de retorno.
2.1 Correspondência de valores
Correspondência de valores, ou seja Java
, correspondência de inteiro, caractere ou string semelhante . Mas onde é protegida a correspondência (pode ser entendida como correspondência condicional por padrão)
//字符匹配
def main(args: Array[String]): Unit = {
val charStr = '6'
charStr match {
case '+' => println("匹配上了加号")
case '-' => println("匹配上了减号")
case '*' => println("匹配上了乘号")
case '/' => println("匹配上了除号")
//注意:不满足以上所有情况,就执行下面的代码
case _ => println("都没有匹配上,我是默认值")
}
}
//字符串匹配
def main(args: Array[String]): Unit = {
val arr = Array("hadoop", "zookeeper", "spark")
val name = arr(Random.nextInt(arr.length))
name match {
case "hadoop" => println("大数据分布式存储和计算框架...")
case "zookeeper" => println("大数据分布式协调服务框架...")
case "spark" => println("大数据分布式内存计算框架...")
case _ => println("我不认识你...")
}
}
//守卫式匹配
def main(args: Array[String]): Unit = {
//守卫式
val character = '*'
val num = character match {
case '+' => 1
case '-' => 2
case _ if character.equals('*') => 3
case _ => 4
}
println(character + " " + num)
}
2.2 Tipo de correspondência
A correspondência de tipo é uma Java
vantagem relativa , Java
não pode ser feita. O formato de correspondência é o seguinte : case 变量名:类型
, o nome da variável pode ser usado em seu _
lugar
//类型匹配
def typeMathc (x: Any) = {
x match {
case _: String => println("字符串")
case _: Int => println("整形")
case _: Array[Int] => println("正星星数组")
case _ => println("nothing")
}
}
2.3 Combinando matrizes, tuplas, conjuntos
Diferente da correspondência de tipo, a correspondência de tipo só pode corresponder ao tipo grande inteiro e esse tipo de correspondência pode ser semelhante a um determinado tipo, mas também pode limitar alguns elementos do tipo correspondente
//数组模式匹配
def arrayMatch(x: Array[Int]) = {
x match {
case Array(1,x,y) => println(x + ":" + y)
case Array(1) => println("only 1 ....")
case Array(1,_*) => println("1 开头的")
case _ => println("nothing....")
}
}
//list模式匹配
def listMatch() = {
val list = List(3, -1)
//对List列表进行模式匹配,与Array类似,但是需要使用List特有的::操作符
//构造List列表的两个基本单位是Nil和::,Nil表示为一个空列表
//tail返回一个除了第一元素之外的其他元素的列表
//分别匹配:带有指定个数元素的列表、带有指定元素的列表、以某元素开头的列表
list match {
case x :: y :: Nil => println(s"x: $x y: $y")
case 0 :: Nil => println("only 0")
case 1 :: _ => println("1 ...")
case _ => println("something else")
}
}
//元组匹配
def tupleMatch() = {
val tuple = (5, 3, 7)
tuple match {
case (1, x, y) => println(s"1, $x, $y")
case (_, z, 5) => println(z)
case _ => println("else")
}
}
Quando não há valor de gravação na matriz, as seguintes correspondências são equivalentes e qualquer parâmetro é igual à correspondência de tipo completa
case Array(_*) => println("*")
case _: Array[Int] => println("整个数组")
2.4 Amostra de correspondência de classe
A classe de caso é uma classe especial em Scala. Quando a classe de amostra é declarada, as seguintes coisas acontecem automaticamente:
Os parâmetros recebidos pelo construtor principal geralmente não precisam ser explicitamente modificados com var ou val, Scala usará automaticamente val para modificar
O objeto complementar é definido automaticamente para a classe de amostra e o método de aplicação é fornecido. O objeto correspondente pode ser construído sem a nova palavra-chave
Os métodos toString, equals, hashCode e copy serão gerados, a menos que as definições desses métodos sejam fornecidas explicitamente
Herdar as duas características de Produto e Serializável, o que significa que a classe de amostra pode ser serializada e aplicada ao método do Produto
A classe de caso é múltiplos casos, seguidos por parâmetros de construção, e o objeto de caso é singleton.
Além disso, métodos e campos podem ser adicionados à classe de amostra da classe de caso e podem ser usados para correspondência de padrões. Como entender a correspondência de padrões da classe de amostra? Ao usar a vinculação dinâmica, você pode julgar pela herança da classe de amostra se um objeto pertence a um objeto de subclasse, e a interface orientada para a classe pai pode simplificar o design de programação. isInstanceOf
Semelhante ao que foi mencionado na primeira parte , ao mesmo tempo, a classe de amostra pode aceitar parâmetros de entrada para operações de subclasse correspondentes.
class Amount
//定义样例类Dollar,继承Amount父类
case class Dollar(value: Double) extends Amount
//定义样例类Currency,继承Amount父类
case class Currency(value: Double, unit: String) extends Amount
//定义样例对象Nothing,继承Amount父类
case object Nothing extends Amount
object CaseClassDemo {
def main(args: Array[String]): Unit = {
judgeIdentity(Dollar(10.0))
judgeIdentity(Currency(20.2,"100"))
judgeIdentity(Nothing)
}
//自定义方法,模式匹配判断amt类型
def judgeIdentity(amt: Amount): Unit = {
amt match {
case Dollar(value) => println(s"$value")
case Currency(value, unit) => println(s"Oh noes,I got $unit")
case _: Currency => println(s"Oh noes,I go")
case Nothing => println("Oh,GOD!")
}
}
}
2.5 Combinar com valor sem valor
Scala Option
O tipo de opção é usado para indicar que um valor é opcional, com ou sem valor. Option[T]
É um contêiner de valores opcionais do tipo T, valores que podem ser obtidos por meio de get()
funções Option
. Se o valor existir, Option[T]
é um Some
. Se não existe, Option[T]
é o objeto None
. Option
Geralmente é usado em combinação com a correspondência de padrões para determinar se uma variável tem um valor ou nenhum valor.Vamos dar uma olhada nesta correspondência com Map
o valor de retorno fornecido abaixo Option
.
val grades = Map("jacky" -> 90, "tom" -> 80, "jarry" -> 95)
def getGrade(name: String): Unit = {
val grade: Option[Int] = grades.get(name)
grade match {
case Some(grade) => println("成绩:" + grade)
case None => println("没有此人成绩!")
}
}
def main(args: Array[String]): Unit = {
getGrade("jacky")
getGrade("张三")
}
3. Resumo
Scala
Na correspondência de padrões, é usado para simplificar o código ou para obter uma correspondência incerta mais poderosa determinada, mas também pode personalizar a correspondência de padrões, o tempo de correspondência utilizando métodos apply
e automaticamente unapply
. Wu Xie, Xiao San Ye, um pequeno novato no fundo, big data e inteligência artificial. Por favor, preste atenção a mais