Nim教程【十三】(调查:你会顺手帮博客园点个广告吗?)

类型转换

Nim支持显示类型转换和隐式类型转换

使用casts操作符完成显示类型转换工作,

显示类型转换工作是编译期完成的工作,是位模式的

隐式类型转换也是编译期完成的工作,不是位模式的

让我们来看一下下面的代码

proc getID(x: Person): int =
  Student(x).id

在上面的代码中

如果x变量的类型不是Student类型(Person类型是Student类型的父类型)

那么会抛出一个InvalidObjectConversionError异常。

对象变型

通常情况下,可变的对象类型实际意义更大一些

(译注:这是面向对象三大要素之一“多态”的重要组成部分)

来看下面的代码:

# This is an example how an abstract syntax tree could be modelled in Nim
type
  NodeKind = enum  # the different node types
    nkInt,          # a leaf with an integer value
    nkFloat,        # a leaf with a float value
    nkString,       # a leaf with a string value
    nkAdd,          # an addition
    nkSub,          # a subtraction
    nkIf            # an if statement
  Node = ref NodeObj
  NodeObj = object
    case kind: NodeKind  # the ``kind`` field is the discriminator
    of nkInt: intVal: int
    of nkFloat: floatVal: float
    of nkString: strVal: string
    of nkAdd, nkSub:
      leftOp, rightOp: PNode
    of nkIf:
      condition, thenPart, elsePart: PNode

var n = PNode(kind: nkFloat, floatVal: 1.0)
# the following statement raises an `FieldError` exception, because
# n.kind‘s value does not fit:
n.strVal = ""

从上面的代码中可以看出

有继承关系的对象之间做类型转换非常简单

访问无效的对象属性会引发一个异常

方法

对象的方法有两个缺点

  • 程序员难以在运行期为一个类型增加方法(或者只能用丑陋的方法才能做到)
  • 很多时候方法的参数是不确定的

Nim为了避免类似的问题,不分配方法到类中

后面我们将了解Nim的动态绑定方法的特性

方法调用

可以使用点操作符调用对象的方法

obj.method(args)

而不是

method(obj,args)

如果没有参数,则可以省略小括号

obj.method

方法调用是不受对象限制的,来看看下面的代码:

echo("abc".len) # is the same as echo(len("abc"))
echo("abc".toUpper())
echo({‘a‘, ‘b‘, ‘c‘}.card)
stdout.writeln("Hallo") # the same as writeln(stdout, "Hallo")

我们再来看看面向对象的写法

import strutils

stdout.writeln("Give a list of numbers (separated by spaces): ")
stdout.write(stdin.readLine.split.map(parseInt).max.`$`)
stdout.writeln(" is the maximum!")

是不是感觉很糟糕呢?

属性

请看如下代码来了解对象的属性

type
  Socket* = ref object of RootObj
    FHost: int # cannot be accessed from the outside of the module
               # the `F` prefix is a convention to avoid clashes since
               # the accessors are named `host`

proc `host=`*(s: var Socket, value: int) {.inline.} =
  ## setter of hostAddr
  s.FHost = value

proc host*(s: Socket): int {.inline.} =
  ## getter of hostAddr
  s.FHost

var s: Socket
new s
s.host = 34  # same as `host=`(s, 34)

这个Socket类型,有一个host属性,获取这个属性的值时

执行第二个方法,设置这个属性的值时,执行第一个方法

(这个例子中也演示了inline方法)

我们可以在类型中重载方括号,以提供与数组相类似的属性

请看如下代码:

type
  Vector* = object
    x, y, z: float

proc `[]=`* (v: var Vector, i: int, value: float) =
  # setter
  case i
  of 0: v.x = value
  of 1: v.y = value
  of 2: v.z = value
  else: assert(false)

proc `[]`* (v: Vector, i: int): float =
  # getter
  case i
  of 0: result = v.x
  of 1: result = v.y
  of 2: result = v.z
  else: assert(false)

动态指派方法

需要使用method关键字来代替proc关键字

才能使用动态指派的特性

来看下面的代码

type
  PExpr = ref object of RootObj ## abstract base class for an expression
  PLiteral = ref object of PExpr
    x: int
  PPlusExpr = ref object of PExpr
    a, b: PExpr

# watch out: ‘eval‘ relies on dynamic binding
method eval(e: PExpr): int =
  # override this base method
  quit "to override!"

method eval(e: PLiteral): int = e.x
method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b)

proc newLit(x: int): PLiteral = PLiteral(x: x)
proc newPlus(a, b: PExpr): PPlusExpr = PPlusExpr(a: a, b: b)

echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))

再来看看下面的代码

type
  Thing = ref object of RootObj
  Unit = ref object of Thing
    x: int

method collide(a, b: Thing) {.inline.} =
  quit "to override!"

method collide(a: Thing, b: Unit) {.inline.} =
  echo "1"

method collide(a: Unit, b: Thing) {.inline.} =
  echo "2"

var a, b: Unit
new a
new b
collide(a, b) # output: 2

因为决议是从左到右执行的

所以最后一个collide方法优于前面两个collide方法

毕竟a和b都是Unit类型的

注意:Nim不产生虚方法表(C#.net是需要虚方法表的),

但是会生成调用树(这样做可以提升性能表现)

时间: 2024-11-08 09:56:31

Nim教程【十三】(调查:你会顺手帮博客园点个广告吗?)的相关文章

【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结

去年就知道有这个功能,不过没去深究总结过,最近有写网络博客的欲望了,于是又重新拾起这玩意儿. 具体到底是用Windows Live Writer 2012还是用Word 2013,个人觉得看个人,因为这2个软件各有优点,各有缺点. 1.首先用LiveWriter发博客显然更专业,发布后的效果也与本地最接近,但是在编辑功能上肯定大不如Word,另外一个最大缺点是它本地保存的格式不是doc. 2.而Word的优点不言而喻,我们天天用Word,用Word就能发博客这简直就是一个天大的好消息,但用Wor

Windows Live Writer离线博客工具使用教程(适用于博客园、CSDN、51CTO等等博客)

文章背景 写博客不单是一种记录方式,更是一种工作习惯,与朋友一起分享是一件很快乐的事情,以前写博客,我们都会面临博客自带编辑器上各种头疼问题,比如排版.样式.功能局限性等等.但这些阻止不了我写下去的决心.一天突然奇想搜索下是否有那种离线博客发布的工具,没想到一谷歌,结果是,我竟然Out了好多年!泪奔啊- 文章主题 在网上查找离线博客之类的工具,发现各式各样都有!参差不齐!这里我就不一一举例了.最后决定使用微软一款开源日志发布工具Windows Live Writer.之所以用它,主要是原因有三:

(转)【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结

去年就知道有这个功能,不过没去深究总结过,最近有写网络博客的欲望了,于是又重新拾起这玩意儿. 具体到底是用Windows Live Writer 2012还是用Word 2013,个人觉得看个人,因为这2个软件各有优点,各有缺点. 1.首先用LiveWriter发博客显然更专业,发布后的效果也与本地最接近,但是在编辑功能上肯定大不如Word,另外一个最大缺点是它本地保存的格式不是doc. 2.而Word的优点不言而喻,我们天天用Word,用Word就能发博客这简直就是一个天大的好消息,但用Wor

【转】【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结

原文地址:http://www.cnblogs.com/liuxianan/archive/2013/04/13/3018732.html 去年就知道有这个功能,不过没去深究总结过,最近有写网络博客的欲望了,于是又重新拾起这玩意儿. 具体到底是用Windows Live Writer 2012还是用Word 2013,个人觉得看个人,因为这2个软件各有优点,各有缺点. 1.首先用LiveWriter发博客显然更专业,发布后的效果也与本地最接近,但是在编辑功能上肯定大不如Word,另外一个最大缺点

Python爬虫入门教程:博客园首页推荐博客排行的秘密

1. 前言 虽然博客园注册已经有五年多了,但是最近才正式开始在这里写博客.(进了博客园才知道这里面个个都是人才,说话又好听,超喜欢这里...)但是由于写的内容都是软件测试相关,热度一直不是很高.看到首页的推荐博客排行时,心里痒痒的,想想看看这些大佬究竟是写了什么文章这么受欢迎,可以被推荐.所以用Python抓取了这100位推荐博客,简单分析了每个博客的文章分类,阅读排行榜,评论排行榜及推荐排行榜,最后统计汇总并生成词云.正好这也算是一篇非常好的Python爬虫入门教程了. 2. 环境准备 2.1

【转】Windows Live Writer离线博客工具使用教程(适用于博客园、CSDN、51CTO等等博客)

文章背景 写博客不单是一种记录方式,更是一种工作习惯,与朋友一起分享是一件很快乐的事情,以前写博客,我们都会面临博客自带编辑器上各种头疼问题,比如排版.样式.功能局限性等等.但这些阻止不了我写下去的决心.一天突然奇想搜索下是否有那种离线博客发布的工具,没想到一谷歌,结果是,我竟然Out了好多年!泪奔啊- 文章主题 在网上查找离线博客之类的工具,发现各式各样都有!参差不齐!这里我就不一一举例了.最后决定使用微软一款开源日志发布工具Windows Live Writer.之所以用它,主要是原因有三:

博客园美化教程大集合(超详细,看这篇就够了)

阅读目录: 1. 前言 2. 定制自己的博客 0. 美化整体效果 1. 准备工作 2. 自定义个性化导航栏 3. 添加顶部博主信息 4. 添加顶部滚动公告 5. 为博客文章添加目录导航 6. 添加分享功能按键 7. 定制推荐和反对按键的炫酷样式 8. 添加快速返回顶部的功能按键 9. 添加打赏功能按键 10. 添加页面放大缩小功能按键 11. 添加Github图标及链接 12. 添加公告栏图片 13. 添加公告栏文字信息 14. 添加公告栏个性时钟 15. 为公告栏添加访客来源统计 16. 为公

Word2016编辑博客发布至博客园教程

用word2016编辑博客发布至博客园教程 博客园的编辑器不够灵活,且官方推荐的windows live writer不再更新,不知什么原因windows10安装不了,markdown的语法不太熟悉,所以用word编辑博客既方便又快捷. 点击文件à共享à发布至博客 在弹出对话中点击立即注册à在"选择博客提供商中选中其他"à点击下一步 在弹出注册框中设置如下: 再点击图片选项,在弹出框中选择"我的博客提供商 测试 博客效果 原文地址:https://www.cnblogs.co

》【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结《 第一:起步测试002()

http://www.cnblogs.com/liuxianan/archive/2013/04/13/3018732.html(感谢小茗同学) 去年就知道有这个功能,不过没去深究总结过,最近有写网络博客的欲望了,于是又重新拾起这玩意儿. 具体到底是用Windows Live Writer 2012还是用Word 2013,个人觉得看个人,因为这2个软件各有优点,各有缺点. 1.首先用LiveWriter发博客显然更专业,发布后的效果也与本地最接近,但是在编辑功能上肯定大不如Word,另外一个最