Core features
在很多方面Nim都是非常创新的.Nim的许多特征在其他任何编程语言中都找不到.如果你喜欢学习新的编程语言,特别是有有趣和独特特征的编程语言,Nim语言就是你的不二选择.
在这部分,我们将看看Nim的核心特征.正是这些特征使Nim从其他语言中脱颖而出.
Metaprogramming
最实用以及某种意义上Nim最独特的特征是其广泛的元编程的支持.元编程绝不是Nim的一个发明,但是没有任何有元编程特性的编程语言的元编程是如此广泛,同时像Nim一样容易接受.如果你熟悉Lisp,你可能已经有一些元编程的经验.
Nim中的元编程是特殊的,因为有很好元编程特性的语言通常属于Lisp语言家族.如果你已经熟悉其他语言如,Java或者Python,你将发现相比Lisp,Nim很容易开始使用.你也将发现很自然学习Nim的元编程特性相比Lisp.
元编程通常是一个高级话题.它是一个非常强大的特性,将在这本书的第9章给出更详细的介绍.元编程带来的一个主要好处是它能够移出样板代码.元编程也允许创建领域特定语言,它可用于在Nim源码中包括mini-languages.例如:
html:
body:
p: "Hello World"
上面的mini-language指定一些HTML代码.在这个例子中<html>
,<body>
and<p>Hello World</p>
将被上面的代码返回.Nim中的元编程允许你定义这样的语言并且可以自由的与普通Nim代码混合.这样的语言有很多的用例,例如,上面的那个可以用来为你的web应用创建HTML模板.
Style insensitivity
Nim的另一个有趣且特有独一无二的特性是类型不敏感.程序员必须做的最难的事情之一是为命名各种标识符,如,变量,函数,以及模块.在很多编程语言中,标识符不能包含空格,所以程序员被迫采用在一个名字中分离多个单词的方式.在通常情况下,设计多个不同的方法.最受欢迎的是snake_case
和camelCase
至今仍在讨论.Nim允许你使用snake_case
,即使该标识符已使用camelCase
定义,反之亦然.这允许你使用你喜欢的风格编写代码,即使你所使用的库为它的标识符使用一个不同的风格.
Listing 1.1 Style insensitivity
import strutils 1
echo("hello".to_upper()) 2
echo("world".toUpper()) 3
- strutils模块定义了一个名为toUpper的过程
- 我们可以使用snake_case调用它
- 或者,按照它最初使用的camelCase定义调用
这可以工作因为Nim认为标识符to_upper
和toUpper
是等价的.当比较的时候,会忽略非首字母的大小写及下划线.
Powerful type system
区别编程语言的特征之一是它们的类型系统.一个类型系统的主要目的是在你的程序中减少bug的可能性.一个好的系统提供的其他好处是特定编译器优化的可能性,更好的文档的代码等.
有很多不同的类别用于分类一个编程语言的类型系统.主要的类别是静态和动态类型系统.大多数情况下,一个编程语言并不在这些类型系统的极端,它是两种类型系统的合并.这样做是由于都需要一定的权衡.虽然静态类型在编译时发现更多的错误,但它也降低了程序编写处的速度。动态类型是完全相反的.
Nim倾向于静态类型.但是不像其他的静态类型编程语言,它也包含很多特性使得它快速开发.类型推断就是一个很好的例子,类型可以通过编译器推断,不需要你自己写出类型,当然除非你选择写出它们的类型.你的程序仍然是无bug并且你的开发速度并不阻碍.Nim也结合了动态类型检查的一些特性,比如运行时类型信息,允许动态调度的功能.
类型系统的一个方面是确保你的程序是无bug,通过内存安全验证.一些编程语言如C不是内存安全,因为在内存没有为它分配使用的情况下,它允许程序访问内存.其他编程语言是内存安全的,以程序访问内存底层细节为代价,在一些情况下是必要的.Nim结合两者,它是内存安全的,只要在你的程序中不使用任何不安全类型如ptr
,同时当与C库连接时ptr类型是必须的,支持这些不安全的特征使得Nim成为一个强大的系统级编程语言.
最后,Nim的类型系统最重要的的特性之一是有能力使用泛型编程.Nim中的泛型允许大量的代码重用而不牺牲类型安全.泛型允许的事情之一是指定一个过程可以接受多个不同的类型.例如,有一个showNumber
过程,它在屏幕上输出整型和浮点型.
proc showNumber(num: int | float) =
echo(num)
showNumber(3.14)
showNumber(42)
上面的showNumber
过程的参数列表中接收一个int
类型或者一个float
类型.|
操作符用于指定int
和float
都可以传递给showNumber
过程.这个清单是一个Nim泛型的简单演示,在下面的章节中你将学习到更多关于Nim的类型系统以及泛型.
Compilation
在前面的部分我已经提到,Nim编译器首先将源代码编译到C,然后为C编译器提供源代码.在How does it work?部分你将学习到更多关于这如何工作的细节,但是现在让我们谈谈这种编译模式具有的很多实用的优点.C语言是一个非常成熟的系统编程语言,它已经使用超过40年.C是最轻便的编程语言之一,有多种实现,如Windows, Linux, Mac OS X, x86, amd64, arm和其他更多鲜为人知的操作系统和平台.C支持从一个超级计算到一个微处理器,它们也非常成熟和实现许多强大的优化使得C非常有效率.
Nim结合C的这些优势,包括它的可移植性,广泛使用和效率.
编译到C的一个特定好处是不像运行在JVM上的编程语言,如Java,Scala和Clojure,以及解释性编程语言如Python,Ruby,以及Perl.Nim软件可以在没有任何依赖下运行.这使得你应用程序的发布非常简单.另一种情况这一个巨大的优势是当部署web应用程序到多个web服务器时,依赖关系的缺乏意味着你可以简单下载你的web应用程序的二进制执行文件,并且在服务器上不需要安装任何额外的依赖运行它.这也使得Nim非常适合嵌入式系统中资源如内存磁盘空间是有限的.
编译到C也使得它很容易使用存在的C和C++库.这样的实现首先包装这些库,包装可以手动完成或者使用一个叫做c2nim的工具,该工具自动生成这些包装器.
NOTE c2nim The c2nim tool cannot translate every single piece of C/C++ code out there, in some cases you may need to manually edit parts of the code. Look for more information in Chapter 8.
有很多库都是用C和C++写的,它们大部分非常受欢迎.从Nim你可以非常容易的使用所有的库.这是双向的,所以你也可以写从C以及其他编程语言使用的库.
Nim的编译器也可以将Nim源码编译成Objective C以及JavaScript.Objective C主要用于IOS软件开发.通过编译到Objective C,你能够使用Nim写IOS本地应用.当然这也包含使用Java或者C写Android应用.Nim目前不能编译到Java,但是它编译到C.通过这样,Nim也可以用于创建Android应用.JavaScript是被数十亿网站使用的客户端语言,它有时被称作"网络的汇编语言",因为它是唯一被所有主流的web浏览器所支持的编程语言.通过将Nim编译到JavaScript,你可以使用Nim为web浏览器创建客户端应用程序.
Memory management
C和C++都要求你手动内存管理,小心确保你分配的是一旦回收就不再需要的内存.Nim为你提供另一种使用垃圾收集器管理内存.垃圾收集器被很多人认为应用到某些特定的领域是不合适的,如嵌入式系统以及游戏.出于这个原因,Nim对于不同的应用程序支持不同的垃圾收集器.默认的垃圾收集器是实时垃圾收集器,所以它允许你来指定它应该在收集内存上花费的时间.它很好的适用于实时系统和游戏,因为它不会在未知的时间暂定你的游戏进程.垃圾收集器也可以被完全移出,给你手动管理内存的能力.
TIP Garbage collectors Switching between garbage collectors is easy, you just need to specify the --gc:
<theGc>
flag during compilation and replace<theGc>
with one of either markandsweep , boehm , or none .
关于Nim还有更多的内容,不仅是独特和创新的特性,而且从现有编程语言独特组成特性使Nim成为一个非常独特的整体.现在让我来告诉你Nim是如何工作的.