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-09-11 07:11:22

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

【超详细教程】使用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,另外一个最大缺点是它

iOS中 语音识别功能/语音转文字教程详解 韩俊强的博客

原文地址:http://blog.csdn.net/qq_31810357/article/details/51111702 前言:最近研究了一下语音识别,从百度语音识别到讯飞语音识别:首先说一下个人针对两者的看法,讯飞毫无疑问比较专业,识别率也很高真对语音识别是比较精准的,但是很多开发者和我一样期望离线识别,而讯飞离线是收费的:请求次数来讲,两者都可以申请高配额,针对用户较多的几乎都一样.基于免费并且支持离线我选择了百度离线语音识别.比较简单,UI设计多一点,下面写一下教程: 1.首先:需要的

实战博客园访问流量计数器-三步操作简化教程

引子:你是否为无法看到自己园子的访问流量而黯然神伤呢? 每写一篇文字,你是都否期待有人来阅读,是否期待有人来支持,与你共享心得和体会呢?注册园子有几个月了,很喜欢这么一个平台,总可以找到心意相通的朋友,也发现了一些不足.包括无法看到自己博客空间的访问流量计数.这个问题得向Dudu反应一下.没办法只能自己想辙啊,感谢度娘,感谢博客园,终于找到了解决问题的方法,特整理处理,希望与大家共享. 第一步:风格选择 首先我们登录到站点:http://www.amazingcounters.com/sign-

iOS中 最新微信支付/最全的微信支付教程详解 韩俊强的博客

亲们, 首先让我们来看一下微信支付的流程吧. 1. 注册微信开放平台,创建应用获取appid,appSecret,申请支付功能,申请成功之后会返回一些参数. 2. 下载微信支付sdk 3. 客户端请求订单,后台与微信后台交互,返回给客户端支付参数 4. 调用微信客户端,由微信客户端和微信服务器打交道: 5. 客户端和服务端都会收到支付结果:(前台消息不可靠,我们需要去后台验证,如果后台没有收到支付通知,后台去微信服务器验证然后将结果返回给客户端) 支付流程图(大家看一下支付流程). 那么我们现在

借光博客园,帮朋友公司发帖求才,觉得机会不错推荐给大家

北京互联网音乐服务上市公司招聘技术开发人才,2年及以上工作经验.年薪6万-16万.半年加薪机会,成长空间巨大,100人以上研发团队.公司这边办公环境很好园区类google不是高楼大厦而是work in nature有山有水有花有草有瀑布有户外咖啡,提供午餐补助,晚餐免费预订(可以定麦当劳KFC汉堡王),交通费补助,阅读买书费补助,通讯费补助,除了五险一金,还有额外的商业医疗保险,看病全报销.公司是产品型,不做项目,不出差,只做一款音乐产品的研发和维护.想体验自己开发的产品有千万粉丝来使用吗?想挑

Nim教程【五】

妈蛋,花了两天时间才搞定博客园的API, 比预期的时间整整多了1天, 不管怎么说,总算把博客园的客户端搞定了 这篇文章就是用博客园的客户端发布的, 先贴张图,给大家看看, 后面我会和博客园的领导商量一下,看看能不能发出来 (当然,如果能的话,我肯定会开源) (这个图片是直接黏贴上传的哦!) ------------------------------ 这是国内第一个关于Nim的系列教程   先说废话   业内的人认为能够直接操作系统硬件的语言才称得上系统级的编程语言 常见的系统级编程语言有:汇编

独立博客搭建教程

博客,又译为网络日志.部落格或部落阁等,是一种通常由个人管理.不定期张贴新的文章的网站.博客上的文章通常根据张贴时间,以倒序方式由新到旧排列.许多博客专注在特定的课题上提供评论或新闻,其他则被作为比较个人的日记.一个典型的博客结合了文字.图像.其他博客或网站的链接.及其它与主题相关的媒体.能够让读者以互动的方式留下意见,是许多博客的重要要素.大部分的博客内容以文字为主,仍有一些博客专注在艺术.摄影.视频.音乐.播客等各种主题.博客是社会媒体网络的一部分. 博客最初的名称是 Weblog,由web

一、搭建篇-使用Github-hexo搭建个人博客教程—总结自己爬过的坑

title: 一.搭建篇 --使用Github+hexo搭建个人博客教程-总结自己爬过的坑 date: 2017-07-05 09:13:18 tags: Bolg hexo - Github 一直想要拥有自己的一个博客,CSDN,那些又觉得不够个性化(主要是觉得逼格不够,哈哈) Github搭建博客的优点: 1.不需要域名和服务器 2.访问自己博客的时候没有广告 3.可以自己修改样式,能根据自己的需求加功能. 首先来一篇预览的博客,让大家看看效果:这是我自己用Github搭建的:https:/

ASP.NET开源博客QBlog模板皮肤制作教程索引贴

最近几天花了点时间,制作了一下教程,写了几篇 开源博客 秋色园 QBlog 模板皮肤制作文章,这里给出一个索引: PS:同时 秋色园 也增加了四套皮肤,目前共有8套皮肤.   1:ASP.NET开源博客QBlog模板制作教程:博客模板皮肤介绍说明(一)   说明:用截图及文字的方式介绍了模板的基础样式及原理. 示例图片: 1:样式文件   2:ASP.NET开源博客QBlog模板制作教程:博客首页-头部[博客标题|博客概要|博客菜单导航|博客登陆注册退出|多语言导航](二)   说明:实战制作: