前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nim教程【十四】

Nim教程【十四】

作者头像
liulun
发布2018-01-12 15:36:20
7890
发布2018-01-12 15:36:20
举报
文章被收录于专栏:liulunliulun

网友@沉没捕鱼,赞助了一台服务器

这个系列的教程写完之后,我们就要开始着手搭建Nim的社区了~

异常

Nim中的异常类型是对象类型

根据惯例,Nim中的异常类型的命名都应该以Error后缀结尾

在system模块中定义了异常类型的基类

所有的异常都应该派生自system.Exception类型

由于我们不清楚异常对象的生命周期,

所以必须在内存堆上为异常的实例分配空间

编译器不允许开发人员在栈上为异常分配空间

你如果想抛出一个异常,你必须为这个异常的msg属性赋值

按照约定,只有在非常特殊的情况下才应该引发异常

打个比方:你不应该为打不开一个文件而引发异常,

因为这个文件有可能是不存在的。

raise语句引发异常

你可以使用raise语句引发一个异常

请看下面的代码

代码语言:javascript
复制
var
  e: ref OSError
new(e)
e.msg = "the request to the OS failed"
raise e

如果raise关键字后面美元后跟着一个异常的实例

那么将再次引发最后一个异常

system模块中还为我们定义了一个newException的方法

请看如下代码:(是不是简化了很多呢)

代码语言:javascript
复制
raise newException(OSError, "the request to the OS failed")

try语句捕获异常

可以用try语句捕获异常

代码语言:javascript
复制
# read the first two lines of a text file that should contain numbers
# and tries to add them
var
  f: File
if open(f, "numbers.txt"):
  try:
    let a = readLine(f)
    let b = readLine(f)
    echo "sum: ", parseInt(a) + parseInt(b)
  except OverflowError:
    echo "overflow!"
  except ValueError:
    echo "could not convert string to integer"
  except IOError:
    echo "IO error!"
  except:
    echo "Unknown exception!"
    # reraise the unknown exception:
    raise
  finally:
    close(f)

如果try代码块中的代码,执行的时候引发了一个异常

那么就会执行相应的except语句

如果后面的except语句没有明确列出这个异常

那么就会后自行最后一个空except语句

这看起来类似if else语句

如果存在finally语句,

那finally语句块内的代码无论如何都会被执行的

如果一个异常没有得到处理

那么这个异常会从堆栈向上传播

这就意味着,调用链上的方法有可能不会被执行

(如果他被执行了,那么他一定在一个finally子句中)

如果你需要访问异常对象

可以使用system模块中的getCurrentException方法或者getCurrentExceptionMsg方法

来看下面的示例代码

代码语言:javascript
复制
try:
  doSomethingHere()
except:
  let
    e = getCurrentException()
    msg = getCurrentExceptionMsg()
  echo "Got exception ", repr(e), " with message ", msg

在方法上做关于异常的注解

如果你用{.raises.}对某一个方法进行了注解

那么在编译期就会检测这个方法(或这个方法所调用到的方法)会不会抛出了某个异常

如果会,则编译不通过

示例代码如下:

代码语言:javascript
复制
proc complexProc() {.raises: [IOError, ArithmeticError].} =
  ...

proc simpleProc() {.raises: [].} =
  ...

这一段我也没怎么看明白,大家自己看原文吧先

泛型

Nim语言的方法参数化、迭代器、等特性都是靠语言本身的泛型特性实现的

这个特性对于强类型容器是非常有用的

来看一下代码

代码语言:javascript
复制
type
  BinaryTreeObj[T] = object # BinaryTree is a generic type with
                            # with generic param ``T``
    le, ri: BinaryTree[T]   # left and right subtrees; may be nil
    data: T                 # the data stored in a node
  BinaryTree*[T] = ref BinaryTreeObj[T] # type that is exported

proc newNode*[T](data: T): BinaryTree[T] =
  # constructor for a node
  new(result)
  result.data = data

proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) =
  # insert a node into the tree
  if root == nil:
    root = n
  else:
    var it = root
    while it != nil:
      # compare the data items; uses the generic ``cmp`` proc
      # that works for any type that has a ``==`` and ``<`` operator
      var c = cmp(it.data, n.data)
      if c < 0:
        if it.le == nil:
          it.le = n
          return
        it = it.le
      else:
        if it.ri == nil:
          it.ri = n
          return
        it = it.ri

proc add*[T](root: var BinaryTree[T], data: T) =
  # convenience proc:
  add(root, newNode(data))

iterator preorder*[T](root: BinaryTree[T]): T =
  # Preorder traversal of a binary tree.
  # Since recursive iterators are not yet implemented,
  # this uses an explicit stack (which is more efficient anyway):
  var stack: seq[BinaryTree[T]] = @[root]
  while stack.len > 0:
    var n = stack.pop()
    while n != nil:
      yield n.data
      add(stack, n.ri)  # push right subtree onto the stack
      n = n.le          # and follow the left pointer

var
  root: BinaryTree[string] # instantiate a BinaryTree with ``string``
add(root, newNode("hello")) # instantiates ``newNode`` and ``add``
add(root, "world")          # instantiates the second ``add`` proc
for str in preorder(root):
  stdout.writeln(str)

上面的示例展示了一个泛型二叉树

通过这个例子,您可以看到,可以用方括号来完成方法的泛型化、泛型迭代器等特性

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档