Nim教程【四】

简介: 这是国内第一个关于Nim的系列教程 先说废话 不得不说Rust也是门不错的语言,园子里 有人曾经说: Rust语言除了library或keyword缩写比...
这是国内第一个关于Nim的系列教程

先说废话
不得不说Rust也是门不错的语言,园子里 有人曾经说:
Rust语言除了library或keyword缩写比较恶心以外其他所有地方完爆go
还有人曾这样评价Rust语言
Rust 可以说是 D 语言二代目, 
没有 D 里的一些经验主义设计, 
而且更函数式, 
作为 a better C++ 当之无愧.
 Pattern matching, Block, Generic 这些东西, Go 有么? 
不好的地方是集成 feature 略贪心, 
指针那么多类型是有道理但是学习者容易被吓跑.
但是,但是Nim兴盛起来,Rust就不算什么了
有人不相信,问我:vczh轮子大神曾经说过这样的话吗?
我只想说:你去找他求证嘛!这样就知道我是不是瞎编的了。
高雅的Nim
宏可以使用命令式编程方式来构造分析树(parse trees),使用Nim并不需要换一种编程风格来来完成元数据编程(这又是在黑.NET吗)

宏不能改变Nim的语法(不能用宏来做语法糖),因为完全就木有这个必要,因为Nim的语法已经足够灵活了

通过缩进来分隔代码块,缩进不能使用tab制表符,这样编译器能更好的处理代码(说这一句有毛用啊?)
方法
别的语言都叫function或者method,Nim给方法叫做Procedures,我们先来看一个方法的定义
proc yes(question: string): bool =
  echo(question, " (y/n)")
  while true:
    case readLine(stdin)
    of "y", "Y", "yes", "Yes": return true
    of "n", "N", "no", "No": return false
    else: echo("Please be clear: yes or no")

if yes("Should I delete all your important files?"):
  echo("I'm sorry Dave, I'm afraid I can't do that.")
else:
  echo("I think you know what the problem is just as well as I do.")
Nim用proc声明一个方法,这个方法的名字叫做yes,要求输入一个string类型的参数,参数名是question,返回一个bool类型的值,用return关键字返回值,并跳出这个方法的作用域(同时也跳出了while循环)
方法中的result
只要一个方法被定义成有返回值的方法, 那么Nim会给你默认创建一个result变量,
你可以在方法中不用声明就使用这个result变量,不管你方法中有没有retun指令,到方法执行结束,都会返回这个result变量
来看看下面的代码
proc sumTillNegative(x: varargs[int]): int =
  for i in x:
    if i < 0:
      return
    result = result + i

echo sumTillNegative() # echos 0
echo sumTillNegative(3, 4, 5) # echos 12
echo sumTillNegative(3, 4 , -1 , 6) # echos 7
如果你又用var 声明了一个result,就会隐藏掉Nim为你默认创建的那个result,这是result就和普通变量没有区别了  
方法中的参数
为了执行效率,在方法体内部不能改变参数的指
如果你只是想在方法体内部使用与参数同名的变量,那么,没关系,
你可以在方法体内部,使用var重新定义一个同名参数,隐藏掉本身的方法参数
这样就可以像普通的变量一样使用它了
proc printSeq(s: seq, nprinted: int = -1) =
  var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len)
  for i in 0 .. <nprinted:
    echo s[i]
在上面的方法中,同时也展示了参数的默认值是怎么设置的。
如果你一定要在方法体内部改变参数的值,
(这是十分常见的,因为这样做可以为调用者提供信息)
那么你可以在声明参数的时候,使用var关键字,就像下面这样:
proc divmod(a, b: int; res, remainder: var int) =
  res = a div b        # integer division
  remainder = a mod b  # integer modulo operation

var
  x, y: int
divmod(8, 5, x, y) # modifies x and y
echo(x)
echo(y)
在上面的方法中,参数res、remainder的值会被改变,而且方法的调用者也会获悉这个改变
丢弃返回值
在主流编程语言中,一个方法存在返回值,如果我们只想调用这个方法,而不使用他的返回值,那我们不理会他的返回值就是了
在Nim中,这是不允许的,你必须显示的丢弃掉他的返回值才行,就像下面的代码一下
discard yes("May I ask a pointless question?")
上面的yes方法声明的时候定义了返回值,如果你不想用它的返回值,就只能用discard显示丢弃掉他的返回值
当然,你可以在声明方法的时候,就显示的声明,这个方法的返回值是可以丢弃的,就像下面这样:
proc p(x, y: int): int {.discardable.} =
  return x + y

p(3, 4) # now valid
具名实参
有的时候一个方法包含很多参数,使用这个方法的人只记得参数的名字,但不记得参数的顺序了,那么你可以使用具名参数来解决这个问题,就像下面这样:
proc createWindow(x, y, width, height: int; title: string;
                  show: bool): Window =
   ...

var w = createWindow(show = true, title = "My Application",
                     x = 0, y = 0, height = 600, width = 800)
这样做,可读性又好,使用起来又方便,真是amazing
当然你可能记得前几个参数的顺序,后面几个参数的顺序不记得了,没关系,你可以这么用
var w = createWindow(0, 0, title = "My Application",
                     height = 600, width = 800, true)


这一篇就写到这里吧
下一篇会写操作符、迭代器等内容
喜欢的人请帮我点一下推荐,谢谢!

目录
相关文章
|
6月前
|
C++
Nim 游戏(C++)
Nim 游戏(C++)
68 0
|
测试技术 数据安全/隐私保护 Windows
Nim之NimShellCodeLoader免杀学习(下)
Nim之NimShellCodeLoader免杀学习
247 0
|
人工智能 决策智能
Nim游戏——简单博弈论
Nim游戏——简单博弈论
118 0
Nim游戏——简单博弈论
|
机器学习/深度学习
LightOJ1186——Incredible Chess(nim游戏)
LightOJ1186——Incredible Chess(nim游戏)
60 0
Nim编码风格
介绍 Nim语言不限制开发人员使用哪种具体的编码风格, 但为了社区的发展,在编写一些标准库的时候还是应该遵从统一的编码风格 这篇文章会列出一系列的编码风格准则,供大家参考。   但值得注意的是,有很多例外场景会与这些准则相悖, 而且,nim语言非常灵活,在一些特定上下文中,这些编码风格准则也不适用。
1081 0
|
索引
Nim教程【十】
openarray类型 注意:openarray类型只能用于参数 固定大小的数组虽然性能不错,但过于呆板,使用取来不是很方便 对于一个方法来说,传入参数如果是一个数组,最好是不要限制数组的长度 也就是说,方法应该能够处理不同大小的数组 openarray类型就是为了满足这样的要求而设计...
1114 0
|
索引
Nim教程【九】
向关注这个系列的朋友们,道一声:久违了! 它并没有被我阉掉,他一定会得善终的,请各位不要灰心 Set集合类型 为了在特殊场景下提高程序的性能设置了Set类型,同时也是为了保证性能,所以Set只能容纳有序类型, Set类型可以被一个大括号实例化: var x = {},x就是一个空的set类型 还...
917 0
|
编译器 容器
Nim教程【十四】
网友@沉没捕鱼,赞助了一台服务器 这个系列的教程写完之后,我们就要开始着手搭建Nim的社区了~ 异常 Nim中的异常类型是对象类型 根据惯例,Nim中的异常类型的命名都应该以Error后缀结尾 在system模块中定义了异常类型的基类 所有的异常都应该派生自system.
1033 0