标签: nim-lang

Nimrod的价值与参考模型是什么?

注意:我不是在询问指针和引用之间的区别,对于这个问题,它完全无关紧要.

有一点我无法明确说明 - 尼姆罗德使用的是什么型号?

就像C++一样 - 你有值并且new你创建了指向数据的指针(在这种情况下,变量可以保存指向指向数据的指针的指针)?

或者像C# - 你有POD类型作为值,但用户定义的对象有引用(隐式)?

我发现只有dereferencing是自动的,就像在Go中一样.

另一种方式.你定义你的新类型,比方说Student(名字,大学,地址).你写:

var student ...?
Run Code Online (Sandbox Code Playgroud)
  1. 使student保持实际数据(的Student类型/类)
  2. 使student持有的指针数据
  3. 使student持有指针的指针数据

或者那些点不可能?

types pointers nim-lang

21
推荐指数
2
解决办法
3753
查看次数

假设没有"并发访问",安全地将内存块"借出"给C中的另一个线程

问题

我想在一个线程中分配内存,并安全地 "释放"指向另一个线程的指针,以便它可以读取该内存.

我正在使用一种翻译成C语言的高级语言.高级语言有线程(未指定的线程API,因为它是跨平台的 - 见下文)并支持标准的C多线程原语,如原子比较交换,但它没有真正记录(没有用法示例).这种高级语言的限制是:

  • 每个线程执行一个事件处理无限循环.
  • 每个线程都有自己的本地堆,由一些自定义分配器管理.
  • 每个线程都有一个"输入"消息队列,可以包含来自任意数量的不同其他线程的消息.
  • 传递队列的消息是:
    1. 对于固定类型的消息
    2. 使用复制

现在,对于大型(不希望复制)或可变大小(我认为数组大小是类型的一部分)消息,这是不切实际的.我想发送这样的消息,这里是我想要实现它的大纲:

  • 消息(请求回复)可以存储"有效负载"内联(复制,固定限制总值大小),或指向发送方堆中数据的指针
  • 消息内容(发送者堆中的数据)由发送线程拥有(分配和释放)
  • 接收线程在完成消息内容时向发送线程发送确认
  • "发送"线程在发送之后不得修改消息内容,直到收到(ack).
  • 应该永远是对内存并行读访问被写入,写之前完成.这应该由消息队列work-flow保证.

我需要知道如何确保这没有数据竞争.我的理解是我需要使用内存栅栏,但我不完全确定哪一个(ATOMIC_RELEASE,...)以及循环中的位置(或者我是否需要任何内容​​).


便携性考虑因素

因为我的高级语言需要跨平台,所以我需要得到答案:

  • Linux,MacOS以及可选的Android和iOS
    • 使用pthreads原语来锁定消息队列:pthread_mutex_initpthread_mutex_lock+pthread_mutex_unlock
  • 视窗
    • 使用Critical Section Objects来锁定消息队列:InitializeCriticalSectionEnterCriticalSection+LeaveCriticalSection

如果它有帮助,我假设以下架构:

  • 用于Windows/Linux/MacOS的英特尔/ AMD PC架构(?).
  • 适用于iOS和Android的未知(ARM?)

并使用以下编译器(您可以假设所有这些编译器的"最近"版本):

  • Windows上的MSVC
  • Linux上的铿锵声
  • Xcode在MacOS/iOS上
  • 适用于Android的CodeWorks for Android

到目前为止,我只在Windows上构建,但是当应用程序完成后,我希望以最少的工作将其移植到其他平台.因此,我试图从一开始就确保跨平台兼容性.


试图解决方案

这是我假设的工作流程:

  1. 读取队列中的所有消息,直到它为空(仅当它完全为空时才阻塞).
  2. 在这里叫一些"记忆围栏"?
  3. 读取消息内容(消息中指针的目标),并处理消息.
    • 如果消息是"请求",则可以处理该消息,并将新消息缓冲为"回复".
    • 如果消息是"回复",则可以释放原始"请求"的消息内容(隐式请求"确认").
    • 如果消息是"回复",并且它本身包含指向"回复内容"的指针(而不是"内联回复"),那么也必须发送"回复确认".
  4. 在这里叫一些"记忆围栏"?
  5. 将所有缓冲的消息发送到适当的消息队列中. …

c multithreading thread-safety nim-lang

21
推荐指数
1
解决办法
597
查看次数

解决线程局部gc限制的常见模式?

在我学习Nim的过程中,我正在研究Nim的并发编程方法.我已经看到了一些关于线程局部垃圾收集限制的评论(例如这里那里),但我仍然没有完全看到这一点的所有含义.

我想知道在Nim中是否存在某种完善的"设计模式"如何处理这些限制?也许有可能考虑一个需要线程间共享/交互的典型示例,并为这样的问题展示可能的惯用解决方案?

到目前为止,我自己试图找到一个好的解决方案并没有真正成功,并导致了这个更具体的问题TChannel.

concurrency garbage-collection nim-lang

19
推荐指数
1
解决办法
473
查看次数

如何将值的类型作为字符串?

我想知道是否可以在运行时从Nim中的值获取类型(int32/float64/string)?

我认为这可以通过"typeinfo"库实现,但我无法理解!

编辑:得到答案,并迅速做到这一点:

import typetraits

type
    MyObject = object
        a, b: int
        s: string

let obj = MyObject(a: 3, b: 4, s: "abc")

proc dump_var[T: object](x: T) =
    echo x.type.name, " ("
    for n, v in fieldPairs(x):
        echo("    ", n, ": ", v.type.name, " = ", v)
    echo ")"

dump_var obj
Run Code Online (Sandbox Code Playgroud)

输出:

MyObject (
    a: int = 3
    b: int = 4
    s: string = abc
)
Run Code Online (Sandbox Code Playgroud)

nim-lang

18
推荐指数
1
解决办法
2609
查看次数

如何使用C++ 11样式的强typedef创建新的基本类型?

我试图在C++中模拟一种与Nim编程语言不同的类型.以下示例将不在Nim中编译,因为编译器捕获变量并 具有不同的类型(),尽管两者都是二进制级别的浮点数:edError: type mismatch: got (Euros, float)

type
  Euros = distinct float

when isMainModule:
  var
    e = Euros(12.34)
    d = 23.3
  echo (e + d)
Run Code Online (Sandbox Code Playgroud)

在C++中执行此操作的一种方法是为浮点数编写包装类.但是这对于导出类型的API不适用,因为它的大小与float不同.或者即使类的大小与浮点数的存储长度匹配,它也永远不会匹配char类型的大小.如果您还为加法,减法等操作实现所有可能的运算符,那么这将起作用,但需要大量输入和复制代码.

诸如创建新原始类型之类的旧问题 具有使用boost的强类型定义的可接受答案.但是,typedef似乎只适用于函数类型签名,typedef不会阻止两个float-inherited类型一起添加并且它们的类型完全改变(好吧,因为只有新类型的错觉):

#include <boost/serialization/strong_typedef.hpp>
#include <stdio.h>

BOOST_STRONG_TYPEDEF(float, money);

void test(money a, float b)
{
    int t = a + b;
    printf("value is %d", t);
}

int main()
{
    money a(5.5);
    int euros(5);
    // This is not caught!
    int dollars = …
Run Code Online (Sandbox Code Playgroud)

c++ boost c++11 nim-lang

17
推荐指数
4
解决办法
6692
查看次数

Nim相当于Python的列表理解

由于Nim与Python共享许多功能,如果它也实现了Python的列表理解,我也不会感到惊讶:

string = "Hello 12345 World"
numbers = [x for x in string if x.isdigit()]
# ['1', '2', '3', '4', '5']
Run Code Online (Sandbox Code Playgroud)

这在Nim实际上是否可行?如果没有,可以用模板/宏实现吗?

python list-comprehension nim-lang

14
推荐指数
3
解决办法
2009
查看次数

将seq [char]转换为字符串

我遇到的情况seq[char]如下:

import sequtils
var s: seq[char] = toSeq("abc".items)
Run Code Online (Sandbox Code Playgroud)

转换s回字符串(即"abc")的最佳方法是什么?字符串化$似乎给了"@[a, b, c]",这不是我想要的.

nim-lang

13
推荐指数
2
解决办法
2806
查看次数

在Nim中写/读二进制文件

在Nim中编写和读取二进制文件的最佳方法是什么?我想将交替的浮点数和整数写入二进制文件,然后能够读取该文件.要用Python编写这个二进制文件,我会做类似的事情

import struct

# list of alternating floats and ints
arr = [0.5, 1, 1.5, 2, 2.5, 3]

# here 'f' is for float and 'i' is for int    
binStruct = struct.Struct( 'fi' * (len(arr)/2) ) 
# put it into string format
packed = binStruct.pack(*tuple(arr))

# open file for writing in binary mode
with open('/path/to/my/file', 'wb') as fh:
  fh.write(packed)
Run Code Online (Sandbox Code Playgroud)

要阅读我会做的事情

  arr = []
  with open('/path/to/my/file', 'rb') as fh:
    data = fh.read()
    for i in range(0, len(data), 8):
      tup = binStruct.unpack('fi', …
Run Code Online (Sandbox Code Playgroud)

io binaryfiles nim-lang

11
推荐指数
1
解决办法
2932
查看次数

如何创建一个nim dll并从c#中调用它

我看过几乎每一个例子,我可以通过谷歌找到,并不能完成任务的最简单的创建一个dll (窗口) nim

任何人都可以一步一步地解释它吗?

我正在使用nimIDE - aporia生成代码.

构建a是否dll需要使用命令行?我想有一个解决方法.

使用aporia IDE\ command line,如何通过编译下面的代码来实现与以下代码相同的结果dll:

extern "C" __declspec(dllexport) int __stdcall return_multiply(int num1, int num2)
{
    return num1 * num2;
}
Run Code Online (Sandbox Code Playgroud)

您可能知道的代码可以从中调用 c#

c# dll ffi dllimport nim-lang

11
推荐指数
1
解决办法
1403
查看次数

如何在 Nim 中迭代元组?

假设我有一个程序getTuple(): (int, int, int)。如何迭代返回的元组?它看起来不像items是为tuple,所以我做不到for i in getTuple()

我最初让这个返回 a sequence,这被证明是一个瓶颈。我可以让它在不影响性能的情况下工作吗?我想作为最后的手段我可以展开我的循环,但有什么办法吗?

nim-lang

11
推荐指数
2
解决办法
863
查看次数