Nim教程【十四】
网友@沉没捕鱼,赞助了一台服务器
这个系列的教程写完之后,我们就要开始着手搭建Nim的社区了~
异常
Nim中的异常类型是对象类型
根据惯例,Nim中的异常类型的命名都应该以Error后缀结尾
在system模块中定义了异常类型的基类
所有的异常都应该派生自system.Exception类型
由于我们不清楚异常对象的生命周期,
所以必须在内存堆上为异常的实例分配空间
编译器不允许开发人员在栈上为异常分配空间
你如果想抛出一个异常,你必须为这个异常的msg属性赋值
按照约定,只有在非常特殊的情况下才应该引发异常
打个比方:你不应该为打不开一个文件而引发异常,
因为这个文件有可能是不存在的。
raise语句引发异常
你可以使用raise语句引发一个异常
请看下面的代码
var
e: ref OSError
new(e)
e.msg = "the request to the OS failed"
raise e
如果raise关键字后面美元后跟着一个异常的实例
那么将再次引发最后一个异常
system模块中还为我们定义了一个newException的方法
请看如下代码:(是不是简化了很多呢)
raise newException(OSError, "the request to the OS failed")
try语句捕获异常
可以用try语句捕获异常
# 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方法
来看下面的示例代码
try:
doSomethingHere()
except:
let
e = getCurrentException()
msg = getCurrentExceptionMsg()
echo "Got exception ", repr(e), " with message ", msg
在方法上做关于异常的注解
如果你用{.raises.}对某一个方法进行了注解
那么在编译期就会检测这个方法(或这个方法所调用到的方法)会不会抛出了某个异常
如果会,则编译不通过
示例代码如下:
proc complexProc() {.raises: [IOError, ArithmeticError].} =
...
proc simpleProc() {.raises: [].} =
...
这一段我也没怎么看明白,大家自己看原文吧先
泛型
Nim语言的方法参数化、迭代器、等特性都是靠语言本身的泛型特性实现的
这个特性对于强类型容器是非常有用的
来看一下代码
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)
上面的示例展示了一个泛型二叉树
通过这个例子,您可以看到,可以用方括号来完成方法的泛型化、泛型迭代器等特性
Nim教程【十四】的更多相关文章
- 无废话ExtJs 入门教程十四[文本编辑器:Editor]
无废话ExtJs 入门教程十四[文本编辑器:Editor] extjs技术交流,欢迎加群(201926085) ExtJs自带的编辑器没有图片上传的功能,大部分时候能够满足我们的需要. 但有时候这个功 ...
- webpack4 系列教程(十四):Clean Plugin and Watch Mode
作者按:因为教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步<webpack4 系列教程(十四):Clean Plugin and Watch Mode>原文地址.更欢迎 ...
- RabbitMQ入门教程(十四):RabbitMQ单机集群搭建
原文:RabbitMQ入门教程(十四):RabbitMQ单机集群搭建 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ...
- WebGL简易教程(十四):阴影
目录 1. 概述 2. 示例 2.1. 着色器部分 2.1.1. 帧缓存着色器 2.1.2. 颜色缓存着色器 2.2. 绘制部分 2.2.1. 整体结构 2.2.2. 具体改动 3. 结果 4. 参考 ...
- Nim教程【四】
这是国内第一个关于Nim的系列教程 先说废话 不得不说Rust也是门不错的语言,园子里 有人曾经说: Rust语言除了library或keyword缩写比较恶心以外其他所有地方完爆go 还有人曾这样评 ...
- 【转】机器学习教程 十四-利用tensorflow做手写数字识别
模式识别领域应用机器学习的场景非常多,手写识别就是其中一种,最简单的数字识别是一个多类分类问题,我们借这个多类分类问题来介绍一下google最新开源的tensorflow框架,后面深度学习的内容都会基 ...
- Redis教程(十四):内存优化介绍
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/142.html 一.特殊编码: 自从Redis 2.2之后,很多数据类型都 ...
- Unity3D脚本中文系列教程(十四)
http://dong2008hong.blog.163.com/blog/static/469688272014032134394/ WWWFrom 类Unity3D脚本中文系列教程(十三)辅助类. ...
- Spring Boot2 系列教程 (十四) | 统一异常处理
如题,今天介绍 SpringBoot 是如何统一处理全局异常的.SpringBoot 中的全局异常处理主要起作用的两个注解是 @ControllerAdvice 和 @ExceptionHandler ...
- Wix 安装部署教程(十四) -- 多语言安装包之用户许可协议
在上一篇中,留下了许可协议的问题,目前已经解决.感谢网友武全的指点! 问题 一般我们是用WixVariable 来设定许可协议.如下所示: <WixVariable Id="WixUI ...
随机推荐
- city-picker 选择省市县的一个控件,好用。
我觉得好奇怪,这么好一个插件,为什么没有设置值的方法,还是我才疏学浅?? 我看有的人做法是把,把源代码里面的自动扫描机制注释掉 // $(function () { // $('[data-toggl ...
- [erlang]supervisor(监控树)的重启策略
1. init函数 init() -> {ok, {SupFlags, [ChildSpec,...]}} | ignore. [ChildSpec,...] 是在init之后默认要启动的子进程 ...
- mysql 乱码问题(程序界面显示正常,mysql command line显示乱码)
今天用java写一个程序,用的是mysql数据库.界面出现乱码,然后写了一个过滤器结果了乱码问题. 但是,当我在mysql command line 中查询数据的时候,在界面上显示正常的数据,在mys ...
- ilspy导致c# dll代码被窃取
不得不放弃.net框架的任何开发!!!微软现在太蛋疼了!!! 不得不放弃.net框架的任何开发!!!微软现在太蛋疼了!!! 不得不放弃.net框架的任何开发!!!微软现在太蛋疼了!!! 不得不放弃.n ...
- css3之景深
perspective属性:(目前仅仅支持-webkit-perspective属性,视点距离) 值:number perspective-origin属性:(视点位置) 值:number% numb ...
- 在DW 5.5+PhoneGap+Jquery Mobile下搭建移动开发环境
移动设备应用开发有多难,只要学会HTML5+Javascript就可以.用Dreamweaver5.5+PhoneGap+Jquery Mobile搭建移动开发环境,轻轻松松开发你自己的应用.让你用普 ...
- Mvc分页扩展类 分页代码 带跳转
public static class HtmlPager { public static MvcHtmlString MvcPager(this HtmlHelper html, string cu ...
- sql server 删除所有 视图、存储过程
删除视图: use 数据库名 declare mycur cursor local for select [name] from dbo.sysobjects where xtype='V' --声 ...
- SVN强制解锁操作
如果是其他人锁定文件,而你期望对此文件操作,可进行偷锁操作: 1,将被锁定文件SVN Check out-到本机硬盘. 2,点击文件右键,选择get lock 3,勾上steal the locks ...
- Mysql主从架构的复制原理及配置详解
一.简述Mysql复制 Mysql复制是通过将mysql的某一台主机的数据复制到其他主机(slaves)上,并且在slaves上重新执行一遍来实现.主服务器每次数据操作都会将更新记录到二进制日志文件, ...