声明一个struct:
type
Vector2D* = object
x*, y*: float32
名字后面带星号就是对module外public, 不带星号就是private.
要创建一个Vector2D: vec = Vector2D(x: 0, y: 0)
object前加上ref就从值拷贝变成了引用拷贝:
type
Image* = ref object
texture*: uint
width*, height*: int
ref相当于指针. 解引用的符号是一对方括号: image[] , 不过访问成员属性时不用写image[].width, 可以直接用句号: image.width
定义成员函数:
proc len*(vec: Vector2D): float32 {.inline.} =
sqrt(vec.x * vec.x + vec.y * vec.y)
可以写 len(vec) , 也可以vec.len()
操作符重载:
proc `+`*(lf, rt: Vector2D): Vector2D {.inline.} =
result.x = lf.x + rt.x
result.y = lf.y + rt.y
操作符用一对``括起来.
可以写vec1 + vec2, 也可以强行写成函数调用的形式`+`(vec1, vec2)
创建基类:
type
Graph2D* = ref object of RootObj
position*: Vector2D
direction*: float32
基类要继承RootObj, 或者注上{.inheritable.}的pragma, 否则默认为final.
继承:
type
Circle* = ref object of Graph2D
radius*: float32
Nim本身没构造函数这种东西, 可以自己写一个:
proc initCircle*(c: Circle, radius: float32) =
initGraph2D(c)
c.radius = radius
proc newCircle*(radius: float32): Circle =
new(result)
initCircle(result, radius)
除了newCircle外还特地加了一个initCircle, 毕竟父类的构筑函数不会被自动调用, 需要手动用initXXX进行对象初始化.
运行时类型判断可以用of:
proc isCircle(g: Graph2D): bool = g of Circle
虚函数:
method isPointIn*(self: Circle, x, y: float32): bool =
let
detX = self.position.x - x
detY = self.position.y - y
r = self.radius
return detX * detX + detY * detY <= r * r
不过Nim实际上不会创建一个虚方法表, 而是创建dispatch trees.