Nim教程【十一】

引用类型和指针类型

不同的引用可以只想和修改相同的内存单元

在nim中有两种引用方式,一种是追踪引用,另一种是非追踪引用

非追踪引用也就是指针,指向手动在内存中分配的对象;

追踪引用指向一个垃圾收集的对象;

非追踪引用是不安全的

然而对于一些低级操作(比如说访问硬件),非追踪引用是不可避免的

追踪引用用ref关键词声明

非追踪引用用ptr关键词声明

可以用[]来解包一个引用(访问一个元组或对象域时要用到)

请看下面的代码:

type
  Node = ref NodeObj
  NodeObj = object
    le, ri: Node
    data: int
var
  n: Node
new(n)
n.data = 9
# no need to write n[].data; in fact n[].data is highly discouraged!

上面代码中最后一行,没必要写成n[].data

使用new()来创建一个新的追踪对象

可以使用alloc或dealloc或realloc函数处理非追踪对象

如果一个引用没有指向任何东西,那么他的值为nil

proc方法指针类型

方法类型是一个方法的指针

(译注:一般函数式的语言中都有这个特性哦)

方法类型的变量默认值为nil

来看一下下面的代码

proc echoItem(x: int) = echo(x)

proc forEach(action: proc (x: int)) =
  const
    data = [2, 3, 5, 7, 11]
  for d in items(data):
    action(d)

forEach(echoItem)

模块

nim允许把一个程序分成若干个模块

一个模块就是一个文件

模块可以起到隐藏信息的作用(译注:面向对象的封装)

模块可以起到分开编译的作用

一个模块可以用import语句导入另一个模块的符号

在一个模块中,只有用星号标记的符号,才能导出给另一个模块

来看看下面的代码:

# Module A
var
  x*, y: int

proc `*` *(a, b: seq[int]): seq[int] =
  # allocate a new sequence:
  newSeq(result, len(a))
  # multiply two int sequences:
  for i in 0..len(a)-1: result[i] = a[i] * b[i]

when isMainModule:
  # test the new ``*`` operator for sequences:
  assert(@[1, 2, 3] * @[1, 2, 3] == @[1, 4, 9])

在这个模块文件中导出了变量x和方法*

在程序开始执行的时候就会执行模块的顶层语句,

程序员可以利用nim的这个特性来初始化一些复杂的数据结构

模块的内部可以通过使用isMainModule内置变量来判断当前模块是否为主模块

来看看下面两个模块的代码:

# Module A
type
  T1* = int  # Module A exports the type ``T1``
import B     # the compiler starts parsing B

proc main() =
  var i = p(3) # works because B has been parsed completely here

main() # Module B
import A  # A is not parsed here! Only the already known symbols
          # of A are imported.

proc p*(x: A.T1): A.T1 =
  # this works because the compiler has already
  # added T1 to A‘s interface symbol table
  result = x + 1

模块的符号的书写要符合module.symbol的语法

如果一个符号在两个模块中都定义过了

而且第三个模块引用了这两个模块

来看看下面三个模块的代码:

# Module A
var x*: string
# Module B
var x*: int# Module C
import A, B
write(stdout, x) # error: x is ambiguous
write(stdout, A.x) # no error: qualifier used

var x = 4
write(stdout, x) # not ambiguous: uses the module C‘s x

但这个规则并不适用于方法或迭代器

对于方法或迭代器来说,适用于重载的规则

来看看下面的代码:

# Module A
proc x*(a: int): string = $a# Module B
proc x*(a: string): string = $a# Module C
import A, B
write(stdout, x(3))   # no error: A.x is called
write(stdout, x(""))  # no error: B.x is called

proc x*(a: int): string = nil
write(stdout, x(3))   # ambiguous: which `x` is to call?
时间: 2024-10-15 16:31:47

Nim教程【十一】的相关文章

RabbitMQ入门教程(十一):消息属性Properties

原文:RabbitMQ入门教程(十一):消息属性Properties 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/vbirdbest/article/details/78698364 分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 简介 发送消息可以为消息指定一些参数 Delivery mode: 是否持久化,1 - Non-persistent,2 -

Nim教程【十四】

网友@沉没捕鱼,赞助了一台服务器 这个系列的教程写完之后,我们就要开始着手搭建Nim的社区了~ 异常 Nim中的异常类型是对象类型 根据惯例,Nim中的异常类型的命名都应该以Error后缀结尾 在system模块中定义了异常类型的基类 所有的异常都应该派生自system.Exception类型 由于我们不清楚异常对象的生命周期, 所以必须在内存堆上为异常的实例分配空间 编译器不允许开发人员在栈上为异常分配空间 你如果想抛出一个异常,你必须为这个异常的msg属性赋值 按照约定,只有在非常特殊的情况

Nim教程【四】

这是国内第一个关于Nim的系列教程 先说废话 不得不说Rust也是门不错的语言,园子里 有人曾经说: Rust语言除了library或keyword缩写比较恶心以外其他所有地方完爆go 还有人曾这样评价Rust语言 Rust 可以说是 D 语言二代目,  没有 D 里的一些经验主义设计,  而且更函数式,  作为 a better C++ 当之无愧.  Pattern matching, Block, Generic 这些东西, Go 有么?  不好的地方是集成 feature 略贪心,  指针

Nim教程【七】

这是国内第一个关于Nim的系列教程 先说废话 很开心,在今天凌晨快一点多的时候拿到了 nim-lang.com:nim-lang.cn:nim-lang.net 这三个域名,到不是为了投资,准备用nim-lang.com做一个社区出来 不知道国内有没有人或者机构打算赞助这个事情的 整型 Nim语言中有10个整型类型 int;int8;int16;int32;int64;uint;uint8;uint16;uint32;uint64 默认的整型类型是int 可以使用尾缀的方式来设置整型的类型,就像

Nim教程【二】

第一篇教程1秒内就被管理员从首页踢掉了 管理员嫌内容太少,没有含金量,这次多写一些. 这应该是国内第一个关于Nim入门的系列教程 好,闲话休提,言归正传 Nim介绍 Nim代码会编译成C语言的代码,再编译成本地机器码,不依赖于虚拟机, 而且生成的可执行文件比较小,不依赖于其他库,分发起来比较方便 拥有一个“非追踪式”的垃圾收集器,这就非常适用于类似游戏这样的“弱实时”系统 让程序员拥有直接操纵内存和访问硬件的权力(手动管理的内存有别于垃圾收集器可收集的内存) 零开销的迭代器 Cross-modu

Nim教程【三】

这是国内第一个关于Nim的系列教程 (至少我百度和必应是没有找到类似的教程) 先说废话 有人说 Golang的编译器/工具链也学互联网行业跟风拿用户当测试,简直一点素质没有. 还有人说 Go社区的风气不是很好,发布半成品成风. 也许有人会说因为Go社区还年轻,但是Node社区也很年轻,虽然很多库功能很弱,但是完成了的功能都是比较完备的. 我就啥也不说了,免得被炮火波及,哈哈! (不管怎么说,我昨天跑到go社区的QQ群里去推Nim,至少是没有被踢掉的,哈哈,而且还有一个人表示对Nim感兴趣) 言归

Nim教程【一】

这应该是国内第一个关于Nim入门的系列教程 什么是Nim 我们先来引述网友 Luikore的一段话: Nim 不是函数式的, 但 Nim 支持卫生宏, 可以做 AST 重写, 可以自定编译规则, 是静态语言中的黑客语言有木有!  自定编译规则甚至可以编译出比 C 代码还快的结果, 作为 a better C 当之无愧.  人家 GC 可以手动步进的啊, 想要什么 feature 自己加(list comprehension? 没问题),  加个 const 就可以做编译期计算了(想想 C++ 和

Nim教程【十】

openarray类型 注意:openarray类型只能用于参数 固定大小的数组虽然性能不错,但过于呆板,使用取来不是很方便 对于一个方法来说,传入参数如果是一个数组,最好是不要限制数组的长度 也就是说,方法应该能够处理不同大小的数组 openarray类型就是为了满足这样的要求而设计的 openarray类型的变量索引总是从0开始 len.low.high等操作同样试用于openarray类型 原则上,任何一个数组都可以被传递到一个openarray参数中,索引的类型并不重要 但是一定要注意:

Nim教程【十五】【完结】

模版 模版是Nim语言中的抽象语法树,它是一种简单的替换机制,在编译期被处理 这个特性使Nim语言可以和C语言很好的运行在一起 像调用一个方法一样调用一个模版 请看如下代码: template `!=` (a, b: expr): expr =   # this definition exists in the System module   not (a == b) assert(5 != 6) # the compiler rewrites that to: assert(not (5 ==