Nim语言OOP

声明一个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.

posted @ 2015-04-04 19:00  pngx  阅读(376)  评论(0编辑  收藏  举报