当前位置: 首页 > news >正文

深圳公司网站建设公司百度seo优化排名

深圳公司网站建设公司,百度seo优化排名,上海市住房和城乡建设管理委员会网站,装修设计软件免费版下载10. 隐式转换与隐式参数 假设编写了一个向量类MyVector,并且包含一些向量的基本操作。因为向量可以与标量做数乘运算,所以需要一个计算数乘的方法“*”,它应该接收一个类型为基本值类的参数,在向量对象myVec调用该方法时&#xf…

10. 隐式转换与隐式参数

假设编写了一个向量类MyVector,并且包含一些向量的基本操作。因为向量可以与标量做数乘运算,所以需要一个计算数乘的方法“*”,它应该接收一个类型为基本值类的参数,在向量对象myVec调用该方法时,可以写成myVec * 2的形式。在数学中,反过来写2 * myVec也是可行的,但在程序中不行。操作符左边是调用对象,反过来写就表示Int对象2是方法的调用者,但是Int类中并没有这种方法。

为了解决上述问题,所有oop语言都会有相应的措施,C++采用友元,Scala采取名为隐式转换的策略,把原来的Int类对象2转换类型,变成MyVector类的对象,这样它就能使用数乘方法。隐式转换属于隐式定义的一种,它将程序员事先写好的定义,允许编译器隐式地插入这些定义来解决类型错误。

10.1 隐式定义的规则

隐式定义有如下约束规则:

  1. 标记规则:只有用关键字implicit标记的定义才能被编译器隐式使用,任何函数,变量或单例对象都可以被标记。其中,标记为隐式的变量和单例对象常用作隐式参数。隐式的函数常用于隐式转换。比如x + y由于x类型错误不能通过编译,编译器会将代码改成convert(x) + y,其中convert是某种可用的隐式转换。如果convert能把x改成某种支持+方法的对象,那么这段代码就可以通过类型检查;
  2. 作用域规则:Scala编译器只会考虑当前作用域内的隐式定义,隐式定义在当前作用域必须是单个标记符,编译器不会展开成A.convert(x) + y的形式,有一个例外是编译器会在与隐式转换相关的源类型和目标类型的伴生对象中查找隐式定义,因此常在伴生对象中定义隐式转换,而不需要显式导入;
  3. 每次一个规则:编译器只会插入一个隐式定义,不会出现convert1(convert2(x)) + y这种嵌套的形式;
  4. 显式优先规则:如果显式定义能通过类型检查,就不必进行隐式转换。

Scala只会在三个地方使用隐式定义:转换到一个预期的类型,转换某个选择接收端,隐式参数。

10.2 隐式地转换到期望类型

Scala编译器对于类型检查比较严格,比如一个浮点数赋值给整数变量,人们可能希望通过截断小数部分完成赋值,但是Scala默认情况下不允许这种丢失精度的转换。可以定义一个隐式转换来完成:

scala> import scala.language.implicitConversionsscala> implicit def doubleToInt(x: Double) : Int = x.toInt
def doubleToInt(x: Double): Intscala> val i: Int = 1.5
val i: Int = 1scala> val i: Int = doubleToInt(2.33)
val i: Int = 2
10.3 隐式地转换接收端

接收端就是指调用方法或字段的对象,调用对象在非法的情况下,被隐式转换成了合法的对象,这是隐式转换最常用的地方。

scala> class MyInt(val i: Int)
// defined class MyIntscala> 1.i
-- [E008] Not Found Error: ---------------------------------------------------------------------------------------------
1 |1.i|^^^|value i is not a member of Int
1 error foundscala> implicit def intToMy(x: Int): MyInt = new MyInt(x)
def intToMy(x: Int): MyIntscala> 1.i
val res0: Int = 1

在定义隐式转换前,Int类没有i字段,所以调用会报错,定义隐式转换后,用一个Int对象构造了一个新的MyInt对象,而MyInt对象就有字段i。1.i被编译器隐式展开成intToMy(1).i

隐式转换因此经常用于模拟新的语法,比如Chisel中大量使用了隐式定义。

映射的键-值对语法键->值其实是一个对偶(键,值),也是隐式转换起作用。

10.4 隐式类

隐式类是一个以关键字implicit开头的类,用于简化富包装类的编写。它不能是样例类,并且主构造方法有且仅有一个参数。此外,隐式类只能位于某个单例对象、类或特质中,不能单独出现在顶层。隐式类的特点是让编译器在相同层次下自动生成一个与类名相同的隐式转换,该转换接受一个与隐式类的主构造方法相同的参数,并用这个参数构造一个隐式类的实例对象来返回。

10.5 隐式参数

函数的最后一个参数列表可以用关键字implicit声明为隐式的,这样整个参数列表的参数都是隐式参数。注意,是整个参数列表,即使括号中有多个参数,也只需要在开头写一个implicit,每个参数都是隐式的,不存在部分隐式部分显式。

当调用函数时,若缺省了隐式参数列表,则编译器尝试插入相应的隐式定义。也可以显式给出参数,但是必须全部缺省或者全部写出,不能只写出一部分。

要让编译器隐式插入参数,就必须实现定义好符合预期类型的隐式变量,隐式单例对象和隐式函数,这些隐式定义也必须用implicit修饰。隐式变量,单例对象,函数在当前作用域的引用必须满足单标识符原则,即不同层次之间需要用import解决。

隐式参数的类型应该是稀有或特定的,类型名称最好能表明该参数的作用,而不是使用Int,String等已经约定好的名称。

class PreferredPrompt(val preference: String)
class PreferredDrink(val preference: String)object Greeter {def greet(name: String)(implicit prompt: PreferredPrompt, drink: PreferredDrink) = {println("Welcome, " + name + ". The system is ready.")print("But while you work, ")println("why not enjoy a cup of " + drink.preference + "?")println(prompt.preference)}
}object JoesPrefs {implicit val prompt: PreferredPrompt = new PreferredPrompt("Yes, master> ")implicit val drink: PreferredDrink = new PreferredDrink("tea")
}

保存后执行编译指令,并进入解释器,执行命令:

jia@J-MateBookEGo:~/scala_test$ scalac test.scala
jia@J-MateBookEGo:~/scala_test$ scala
Jan 13, 2025 1:09:02 PM org.jline.utils.Log logr
Welcome to Scala 3.6.2 (21.0.5, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.scala> :load test.scala
// defined class PreferredPrompt
// defined class PreferredDrink
// defined object Greeter
// defined object JoesPrefsscala> Greeter.greet("Joe")
-- [E172] Type Error: --------------------------------------------------------------------------------------------------
1 |Greeter.greet("Joe")|                    ^|        No given instance of type PreferredPrompt was found for parameter prompt of method greet in object Greeter||        The following import might fix the problem:||          import JoesPrefs.prompt|
1 error foundscala> import JoesPrefs._scala> Greeter.greet("Joe")
Welcome, Joe. The system is ready.
But while you work, why not enjoy a cup of tea?
Yes, master>scala> Greeter.greet("Joe")(prompt, drink)
Welcome, Joe. The system is ready.
But while you work, why not enjoy a cup of tea?
Yes, master>
10.6 含有隐式参数的主构造方法

普通的函数可以含有隐式参数,类的主构造方法也可以包含隐式参数,辅助构造方法不允许出现隐式参数。假设类A仅有一个参数列表,并且该列表是隐式的,那么A的实际定义形式是A()(implicit 参数),也就是比字面上的代码多了一对空括号,无论用new实例化类A,还是被其他类继承,若调用主构造方法时显式地给出隐式参数,就必须写出这对空括号,若隐式参数是编译器自动插入,则空括号可有可无。

scala> class A(implicit val x: Int)
// defined class Ascala> val a = new A(1)
-- Error: --------------------------------------------------------------------------------------------------------------
1 |val a = new A(1)|              ^|              too many arguments for constructor A in class A: ()(implicit x: Int): A
1 error foundscala> val a = new A()(1)
val a: A = A@6caeba36scala> implicit val ORZ = 233
-- Error: --------------------------------------------------------------------------------------------------------------
1 |implicit val ORZ = 233|             ^|             type of implicit definition needs to be given explicitly
1 error foundscala> implicit val ORZ: Int = 233
val ORZ: Int = 233scala> val b = new A
val b: A = A@6a7aa675scala> b.x
val res0: Int = 233scala> val c = new A()
val c: A = A@1534bdc6scala> c.x
val res1: Int = 233

http://www.mmbaike.com/news/91327.html

相关文章:

  • 天津做公司网站最新网站发布
  • 一级做爰片a视频网站偷拍手机优化
  • 开源手机网站系统网站运营课程
  • 中山电子商务网站建设网购平台推广方案
  • 浙江疫情最新消息情况网站seo推广优化教程
  • 南山公安分局网站如何创建网站?
  • 网站开发与支付宝端口连接软文是什么意思?
  • 响应式网站做优化好吗seowhy
  • 绵阳市网站建立线上营销推广方案有哪些
  • 免费课程网站有哪些微信seo排名优化软件
  • 穷游网站 做行程 封面网络运营培训
  • 网站建设宝安全案网络推广公司
  • 福建省人民政府驻上海办事处企业seo整站优化方案
  • 网站风格发展趋势网络营销的特点有哪些特点
  • 建设银行网站地址郑州优化网站关键词
  • 常德市网站建设免费网站大全
  • 网站友情链接对方网站没有加入本站链接对本站有没有影响?自己的网站怎么推广
  • 网站建设流程与步骤东莞网站推广营销网站设计
  • 做科技汽车的视频网站有哪些推广seo优化公司
  • 视频网站备案怎么做湖北seo推广
  • 深圳网站建设ucreatorseo基础入门
  • 网页小游戏点击即玩网络营销seo优化
  • 投资网站建设十八大禁用黄app入口
  • 邓州网站设计免费的编程自学网站
  • 做网站是什么专业什么工作seo实战密码第三版pdf
  • 移动端网站案例怎样看网页的友情链接
  • WordPress css隐藏熊掌号seo外链代发
  • discuz 做网站可以吗做网络推广的团队
  • 网站建设方案 文库如何做营销活动
  • 龙岗网站建设公司哪家好seo怎么做