前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Scala 高级类型

Scala 高级类型

作者头像
Freedom123
发布2024-03-29 09:40:58
720
发布2024-03-29 09:40:58
举报
文章被收录于专栏:DevOpsDevOps

一. 高级类型

1. 视界(“类型类”)

有时候,你并不需要指定一个类型是等/子/超于另一个类,你可以通过转换这个类来伪装这种关联关系。一个视界指定一个类型可以被“看作是”另一个类型。这对对象的只读操作是很有用的。

隐函数允许类型自动转换。更确切地说,在隐式函数可以帮助满足类型推断时,它们允许按需的函数应用。例如:

代码语言:javascript
复制
scala> implicit def strToInt(x: String) = x.toInt
strToInt: (x: String)Int

scala> "123"
res0: java.lang.String = 123

scala> val y: Int = "123"
y: Int = 123

scala> math.max("123", 111)
res1: Int = 123

//视界,就像类型边界,要求对给定的类型存在这样一个函数。您可以使用<%指定类型限制,例如:
scala> class Container[A <% Int] { def addIt(x: A) = 123 + x }
defined class Container

//这是说 A 必须“可被视”为 Int 。让我们试试。
scala> (new Container[String]).addIt("123")
res11: Int = 246

scala> (new Container[Int]).addIt(123) 
res12: Int = 246

scala> (new Container[Float]).addIt(123.2F)
<console>:8: error: could not find implicit value for evidence parameter of type (Float) => Int
       (new Container[Float]).addIt(123.2)
        ^
2.其他类型限制

方法可以通过隐含参数执行更复杂的类型限制。例如,List 支持对数字内容执行 sum,但对其他内容却不行。可是 Scala 的数字类型并不都共享一个超类,所以我们不能使用T <: Number。相反,要使之能工作,Scala 的 math 库对适当的类型 T 定义了一个隐含的 Numeric[T]。 然后在 List 定义中使用它:

代码语言:javascript
复制
sum[B >: A](implicit num: Numeric[B]): B

如果你调用List(1,2).sum(),你并不需要传入一个 num 参数;它是隐式设置的。但如果你调用 List(“whoop”).sum(),它会抱怨无法设置 num。

在没有设定陌生的对象为 Numeric 的时候,方法可能会要求某种特定类型的“证据”。这时可以使用以下类型-关系运算符:

A =:= B A 必须和 B 相等 A <:< B A 必须是 B 的子类 A <%< B A 必须可以被看做是 B

代码语言:javascript
复制
scala> class Container[A](value: A) { def addIt(implicit evidence: A =:= Int) = 123 + value }
defined class Container

scala> (new Container(123)).addIt
res11: Int = 246

scala> (new Container("123")).addIt
<console>:10: error: could not find implicit value for parameter evidence: =:=[java.lang.String,Int]

//类似地,根据之前的隐式转换,我们可以放松约束为可视性:
scala> class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value }
defined class Container

scala> (new Container("123")).addIt
res15: Int = 246
3.结构类型

Scala 支持结构类型 structural types — 类型需求由接口构造表示,而不是由具体的类型表示。

代码语言:javascript
复制
scala> def foo(x: { def get: Int }) = 123 + x.get
foo: (x: AnyRef{def get: Int})Int

scala> foo(new { def get = 10 })                 
res0: Int = 133
4.抽象类型成员

在特质中,你可以让类型成员保持抽象。

代码语言:javascript
复制
scala> trait Foo { type A; val x: A; def getX: A = x }
defined trait Foo

scala> (new Foo { type A = Int; val x = 123 }).getX   
res3: Int = 123

scala> (new Foo { type A = String; val x = "hey" }).getX
res4: java.lang.String = hey

其他

学习: https://www.w3cschool.cn/scala/3gpw1jci.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 高级类型
    • 1. 视界(“类型类”)
      • 2.其他类型限制
        • 3.结构类型
          • 4.抽象类型成员
          • 其他
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档