gpt4 book ai didi

nim-lang - 如何在 Nim 中创建变量别名?

转载 作者:行者123 更新时间:2023-12-05 09:16:55 25 4
gpt4 key购买 nike

我是 Nim 的新手,所以这可能是一个迟钝的问题,但是如何创建一个速记别名变量来简化代码?

例如:

import sdl2
import sdl2.gfx

type
Vector[T] = object
x, y: T

Ball = object
pos: Vector[float]

Game = ref object
renderer: RendererPtr
ball: array[10, Ball]

proc render(game: Game) =
# ...

# Render the balls
for ix in low(game.ball)..high(game.ball):
var ball : ref Ball = game.ball[ix]
game.renderer.filledCircleRGBA(
int16(game.renderer.ball[ix].pos.x),
int16(game.renderer.ball[ix].pos.y),
10, 100, 100, 100, 255)

# ...

我想使用一个较短的别名来访问球的位置,而不是最后一部分:

  # Update the ball positions
for ix in low(game.ball)..high(game.ball):
??? pos = game.ball[ix].pos
game.renderer.filledCircleRGBA(
int16(pos.x),
int16(pos.y),
10, 100, 100, 100, 255)

但是,如果我使用 var 代替 ???,那么我似乎会在 pos 中创建一个副本,然后表示原始文件未更新。 ref 是不允许的,let 不会让我改变它。

这似乎是很自然的事情,所以如果 Nim 不让你这样做我会感到惊讶,我只是在手册或教程中看不到任何内容。

[later] 嗯,除了“滥用”ptr 来实现这一点,但我认为除了 C API 互操作性之外,不鼓励使用 ptr

我所希望的是类似于 Lisp/Haskell 的 let* 构造...

最佳答案

另一种可能更像 Nim 的解决方案是使用模板。 Nim 中的模板只是 AST 级别的简单替换。因此,如果您像这样创建几个模板:

template posx(index: untyped): untyped = game.ball[index].pos.x.int16
template posy(index: untyped): untyped = game.ball[index].pos.y.int16

您现在可以将您的代码替换为:

proc render(game: Game) =
# Render the balls
for ix in low(game.ball)..high(game.ball):
var ball : ref Ball = game.ball[ix]
game.renderer.filledCircleRGBA(
posx(ix),
posy(ix),
10, 100, 100, 100, 255)

这将在编译时转换为您的原始代码,并且不会产生任何开销。它还将保持与原始代码相同的类型安全性。

当然,如果这是您发现自己经常做的事情,您可以创建一个模板来创建模板:

template alias(newName: untyped, call: untyped) =
template newName(): untyped = call

然后可以在您的代码中像这样使用它:

proc render(game: Game) =
# Render the balls
for ix in low(game.ball)..high(game.ball):
var ball : ref Ball = game.ball[ix]
alias(posx, game.ball[ballIndex].pos.x.int16)
alias(posy, game.ball[ballIndex].pos.y.int16)
game.renderer.filledCircleRGBA(
posx(ix),
posy(ix),
10, 100, 100, 100, 255)

如您所见,该解决方案只有在多次使用时才真正有用。另请注意,由于别名模板在 for 循环中展开,创建的模板也将在其中限定范围,因此可以共享一个名称。

当然,在游戏设置中更正常的做法可能是使用更面向对象的方法(恕我直言,这是 OO 真正有意义的少数情况之一,但那是另一个讨论)。如果您为球类型创建一个过程,您可以使用 {.this: self.} 编译指示对其进行注释以节省一些输入:

type
A = object
x: int

{.this: self.}
proc testproc(self: A) =
echo x # Here we can acces x without doing self.x

var t = A(x: 10)
t.testproc()

关于nim-lang - 如何在 Nim 中创建变量别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49396029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com