AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-893254

FreelanceConsultant's questions

Martin Hope
user2138149
Asked: 2025-02-14 22:07:33 +0800 CST

如何控制 std::ranges::iota_view 返回的值的类型?

  • 7

C++ 20 引入std::ranges::iota_view。

for例如,它可以用作循环的一部分。

for (auto i: std::ranges::iota_view(0, 10))

它似乎需要两个模板参数。例如,下面的代码可以编译。

std::ranges::iota_view<int64_t, int64_t>(0, 10)

第一个模板参数是Wwhich should be std::weakly_incrementable。第二个模板参数是Boundwhich should be std::semiregular。

这两个模板参数有什么用处?能用来控制 返回的类型吗iota_view?

换句话说,如果有的话,它们对auto i上面例子中推导的类型有什么影响?

c++
  • 1 个回答
  • 64 Views
Martin Hope
user2138149
Asked: 2025-02-12 22:26:42 +0800 CST

对 `send` 的调用是否与对 `recv` 的调用 1:1 对应?

  • 5

据我所知,这个问题的答案是“是”,但我想检查我的理解并希望获得更详细、更深入的理解。

呼叫 和 的呼叫是否send以 1:1 的比例对应recv?

换句话说,如果一个程序调用通过网络套接字将一些数据发送到另一个网络连接的程序,那么在连接的接收端send是否会有且仅有 1 个调用?(假设缓冲区足够大。)recvrecv

我知道操作系统和其他网络硬件可能会对 IP 数据包进行分段。但是,我的理解是,接收端的操作系统将重新组合分段的数据包,然后通过 向客户端应用程序呈现重新组合的数据包recv。

询问的原因是我想弄清楚在某些情况下是否需要多次调用才能获取通过其他机器上的recv调用发送的所有数据。send

之所以需要这样做,显而易见的原因是 因为send发送的数据量超过了 使用的缓冲区所能容纳的数据量recv。但是,为了回答这个问题,我们假设 发送的最大数据量send可以容纳 使用的缓冲区recv。

sockets
  • 1 个回答
  • 23 Views
Martin Hope
user2138149
Asked: 2025-02-09 05:11:09 +0800 CST

如何构建一个使用protobuf的cmake项目?

  • 5

我正在尝试创建一个使用 protobuf 和 cmake 构建系统的小型 C++ 测试项目。

我设法通过单个目录和单个 来使所有内容正常工作CMakeLists.txt。

然而,这不是一个可扩展的结构。

我尝试的下一个更改是创建一个proto目录,并将文件移动*.proto到该目录中。

该项目不再构建,我不知道如何修复它。

我在网上搜索解决方案,也尝试询问 ChatGPT。ChatGPT 转了好几圈,通过搜索我在网上能找到的有限资源,我发现了似乎变化很大的解决方案。我不清楚在众多变化中哪一个可能是正确的方法,但这很可能是因为我不是这方面的专家cmake,所以无法弄清楚如何将各个部分组合在一起。

这是我目前拥有的:

protobuf-example/
  proto/
    CMakeLists.txt
    message.proto
  CMakeLists.txt
  main.cpp

proto/CMakeLists.txt

我不太确定下面需要什么。我对每行代码的作用有一些了解,但理解得不是太透彻。

set(PROTO_FILES message.proto)
set(GENERATED_PROTO_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated)
file(MAKE_DIRECTORY ${GENERATED_PROTO_DIR})

protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_FILES})

add_library(proto_files STATIC ${PROTO_SRCS})

target_include_directories(proto_files PUBLIC ${Protobuf_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})

target_link_libraries(proto_files PUBLIC ${Protobuf_LIBRARIES})

set(PROTO_GEN_SRCS ${PROTO_SRCS} PARENT_SCOPE)
set(PROTO_GEN_HDRS ${PROTO_HDRS} PARENT_SCOPE)
set(PROTO_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)

message.proto

syntax = "proto3";

message Person {
  string name = 1;
  int32 age = 2;
  string email = 3;
}

CMakeLists.txt

另一方面,我熟悉这些语句,并且我确信我知道每个语句的作用。

cmake_minimum_required(VERSION 3.10)
project(ProtobufExample LANGUAGES CXX)

find_package(Protobuf REQUIRED)

add_subdirectory(proto)

add_executable(protobuf_example main.cpp ${PROTO_GEN_SRCS})

target_include_directories(protobuf_example PRIVATE ${Protobuf_INCLUDE_DIR})

target_link_libraries(protobuf_example PRIVATE ${proto_files})

main.cpp

据我所知,这只是一个标准的例子。

#include <iostream>
#include <fstream>
#include "message.pb.h"

void serializePerson(const std::string& filename) {
    Person person;
    person.set_name("John Doe");
    person.set_age(30);
    person.set_email("[email protected]");

    std::ofstream output(filename, std::ios::binary);
    if (!person.SerializeToOstream(&output)) {
        std::cerr << "Failed to serialize data." << std::endl;
    }
}

void deserializePerson(const std::string& filename) {
    Person person;
    std::ifstream input(filename, std::ios::binary);
    if (!person.ParseFromIstream(&input)) {
        std::cerr << "Failed to parse data." << std::endl;
    } else {
        std::cout << "Name: " << person.name() << "\n"
                  << "Age: " << person.age() << "\n"
                  << "Email: " << person.email() << std::endl;
    }
}

int main() {
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    const std::string filename = "person.data";

    serializePerson(filename);
    deserializePerson(filename);

    google::protobuf::ShutdownProtobufLibrary();
    return 0;
}

错误

具体的错误信息为:

Cannot find source file:

    /home/user/cmake-protobuf-test/protobuf-example/build/proto/message.pb.cc

这很可能是因为build/proto/generated目录是空的。

看起来好像protobuf_generate_cpp没有执行任何操作。但是没有产生与此相关的错误或警告。

c++
  • 1 个回答
  • 34 Views
Martin Hope
user2138149
Asked: 2025-02-09 01:56:05 +0800 CST

为什么我不能获取包含多个元素的结构中某些元素的地址?[重复]

  • 7
此问题这里已有答案:
为什么没有显示字符数据的地址? (8 个回答)
昨天休息。

为什么我不能获取其中元素a和的地址?cstruct

#include <iostream>

struct Silly {
    char a;
    unsigned short b;
    char c;
    double d;
};

int main() {

    auto p_silly = new Silly[2];

    std::cout << "address of a: " << &(p_silly[0].a) << std::endl;
    std::cout << "address of b: " << &(p_silly[0].b) << std::endl;
    std::cout << "address of c: " << &(p_silly[0].c) << std::endl;
    std::cout << "address of d: " << &(p_silly[0].d) << std::endl;

    delete[] p_silly;
}

输出:

address of a: 
address of b: 0x61620d70c6c2
address of c: 
address of d: 0x61620d70c6c8

编译自:

g++ main.cpp -o main -std=c++23
c++
  • 1 个回答
  • 107 Views
Martin Hope
user2138149
Asked: 2025-02-09 01:49:59 +0800 CST

如果这两个指针指向不同数组中的项,那么减去同一类型的两个指针是否有意义?[重复]

  • 4
此问题这里已有答案:
使用两个不同缓冲区的指针运算 (4 个答案)
昨天休息。

这个问题有点傻,但我认为很有趣。

我正在尝试使用指针和对齐,并想知道是否可以减去两个不同的指针,每个指针指向不同数组中的项目。

两个指针相减通常会产生一个值,该值表示数组中两个项之间的元素数量。

例如,这里有一些按预期工作的有效代码:

unsigned short *p_short = new unsigned short[100];
unsigned short *p_1 = &p_short[10];
unsigned short *p_2 = &p_short[20];

std::cout << p_2 - p_1 << std::endl;
// should produce the value `10`.
// There are 10 `unsigned short`s between the
// two pointers.
// Note: NOT `20`. The subtraction does not
// calulate the number of bytes between the
// two pointers.
  • 如果数组是不同类型的数组,则不可能。这会产生类型错误。
  • 如果指针是同一类型,但指向不同数组的元素,这是可能的。

然而,后一种情况,减法的结果有意义吗?

可能的输出示例:这是一个可能不会产生有意义的结果的示例。

auto p1 = new unsigned short[100];
auto p2 = new unsigned short[100];
std::cout << p2 - p1 << std::endl;

输出:104。

(然而我也看到了其他值,例如-6148914691236517216。)

c++
  • 3 个回答
  • 91 Views
Martin Hope
user2138149
Asked: 2025-02-09 01:38:33 +0800 CST

为什么这个 3 字节结构的 `alignof` 值为 1?[重复]

  • 6
此问题这里已有答案:
内存对齐:如何使用 alignof/alignas? (5 个答案)
昨天休息。

我写了一个非常简单的例子,演示了 3 字节的地址对齐struct。

#include <iostream>

struct Silly {
    char a;
    char b;
    char c;
};

int main() {

    std::cout << "sizeof(Silly): " << sizeof(Silly) << std::endl;
    std::cout << "alignof(Silly): " << alignof(Silly) << std::endl;
    auto p_silly = new Silly[2];
    std::cout << "address[0]: " << &p_silly[0] << std::endl;
    std::cout << "address[1]: " << &p_silly[1] << std::endl;
    std::cout << "stride: " << &p_silly[1] - &p_silly[0] << std::endl;
    delete[] p_silly;
}

用 编译它g++ -std=c++23,我发现以下结果:

sizeof(Silly): 3
alignof(Silly): 1
address[0]: 0x63b1ada176c0
address[1]: 0x63b1ada176c3
stride: 1

这个输出对我来说没有任何意义。

sizeof() = 3是合理的,因为结构体包含 3 个字节的数据。没有填充,因为每个字段都是一个char,处理器可以从任何地址加载和存储单个字节。

alignof() = 1对我来说没有任何意义。对齐是指可以分配对象的连续地址之间的字节数。我希望在3这里看到一个值?

这两个地址表明两个地址struct Silly相邻分配,没有填充。第二个对象的地址比第一个对象的地址长 3 个字节。这是有道理的。

stride一开始我很困惑,但我意识到这是两个地址之间的元素数。一开始我以为应该是两个地址之间的字节数。

为什么alignof等于1?

c++
  • 1 个回答
  • 86 Views
Martin Hope
user2138149
Asked: 2025-02-08 21:45:50 +0800 CST

为了在 `std::vector<T>` 的分配中获得正确对齐的内存,`T` 的选择重要吗?

  • 6

Astd::vector<char>包含指向某个堆分配缓冲区的指针。

考虑到内存对齐问题,内存分配返回的分配缓冲区是否保证仅针对类型正确对齐char,或者是否会对齐到某些常见值,例如 4 或 8 个字节?(或者未指定?)

举例来说,默认分配器是new。调用new可能会返回任意内存地址。但它真的是任意的吗?

  • 也许在 64 位机器上它是 8 字节对齐的?
  • T也许它与所使用的类型一致std::vector<T>?(这似乎是最有可能的选项。)
  • 也许返回的地址是任意的,可以是任何值。(我不认为这是正确的。)
  • 还有别的吗?

问这个问题的原因是我想知道我是否可以安全地将这块内存中包含的字节重新解释为其他类型,例如float,,,等等。doubleuint64_t

从另一个角度看,情况更加明显。(我认为——请纠正我。)

例如,如果我们要求一个std::vector<uint64_t>,那么内存分配返回的、由对象持有的指针std::vector将是 8 字节对齐的。

因此,以如下方式读写数据是安全的:

  • char*
  • 正确对齐(4字节对齐)float
  • 正确对齐(8字节)double
  • 正确对齐(2字节)unsigned short int
  • ... ETC

但是,如果的分配std::vector<char>可以返回 (十进制) 的内存地址1025,那么如果重新解释为任何大于 1 字节宽的类型,显然不能保证在任何偏移量处正确对齐。

我认为我的理解是正确的,但是如果其中任何一点不太合理或者不正确,请在评论中告诉我。


编辑:

我可能已经找到了答案,但我不确定如何解释我所读到的内容。

从:

  • https://en.cppreference.com/w/cpp/memory/new/operator_new

此函数需要返回一个适当对齐的指针,以指向请求大小的对象。

但这是什么意思呢?

对于宽度为 1 字节的对象,这似乎表明任何地址值都是可以接受的。

对于宽度为 2 字节的对象,建议任何偶数值地址都是可以接受的。

对于 4 个字节,为 4 的任意倍数。对于 8 个字节,为 8 的任意倍数。

但是其他值呢?据我所知,x86 中没有从内存加载 3 字节值的指令。如果您请求3 字节宽的值new[T]在哪里,会发生什么?Tstruct

c++
  • 1 个回答
  • 77 Views
Martin Hope
user2138149
Asked: 2025-02-07 23:30:20 +0800 CST

Julia LoadError:在封闭模块“__toplevel__”中创建一个新的全局变量会破坏增量编译,因为副作用不会是永久性的

  • 5

我用 Julia 又名 Julialang 编写了一些代码。

当我尝试运行此代码时,出现以下错误:

LoadError: Creating a new global in closed module `__toplevel__` (FUNCTION_NAME) breaks incremental compilation because the side effects will not be permanent

这个错误意味着什么以及导致它的原因是什么?

我将其中一个模块中的代码精简为:

module ExampleModule

export exampleFunction1
export exampleFunction2

function exampleFunction1()
    # blaa blaa
end

end # <-- Note: See answer below

function exampleFunction2()
    # blaa blaa
end

end
julia
  • 1 个回答
  • 27 Views
Martin Hope
user2138149
Asked: 2025-02-04 04:13:27 +0800 CST

双栈网络服务器未按预期处理 IPv4 请求

  • 6

下面是一个实现双栈网络基础设施的 C++ 服务器的最小工作示例。(这意味着单个套接字可同时处理 ipv4 和 ipv6 连接。)

#include <format>
#include <print>
#include <cstring>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc, char* argv[]) {

    const auto SERVER_PORT = 7778;

    const auto server_fd = socket(AF_INET6, SOCK_STREAM, 0);
    int opt = 0;

    setsockopt(server_fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));

    sockaddr_in6 server_address;
    std::memset(&server_address, 0, sizeof(server_address));

    server_address.sin6_family = AF_INET6;
    server_address.sin6_addr = in6addr_any;
    server_address.sin6_port = htons(SERVER_PORT);
    bind(server_fd, reinterpret_cast<sockaddr*>(&server_address), sizeof(server_address));

    listen(server_fd, 10);

    sockaddr_storage peer_address;
    socklen_t peer_address_length = sizeof(peer_address);
    auto peer_fd = accept(server_fd, reinterpret_cast<sockaddr*>(&peer_address), &peer_address_length);

    if(peer_address.ss_family == AF_INET)
    {
        const auto p_peer_address = &peer_address;
        sockaddr_in* ipv4 = (sockaddr_in*)p_peer_address;
        std::println("Client port (IPv4): {}", ntohs(ipv4->sin_port));
    }
    else if(peer_address.ss_family == AF_INET6)
    {
        const auto p_peer_address = &peer_address;
        sockaddr_in6* ipv6 = (sockaddr_in6*)p_peer_address;
        std::println("Client port (IPv6): {}", ntohs(ipv6->sin6_port));
    }
    else
    {
        throw std::runtime_error("unrecognized ss_family");
    }

    close(peer_fd);
    close(server_fd);

    return 0;
}

但是,它并没有按预期工作。无论客户端是通过 ipv4 还是 ipv6 进行连接,逻辑始终遵循语句else if的分支if。第一个if分支从未运行,表示没有与该系列建立任何连接AF_INET。

两个客户端似乎都可以正常工作。当连接启动时,服务器会做出响应 - 无论客户端连接类型如何,都会打印 ipv6 消息。(ipv4 或 ipv6)

如果有什么区别的话,客户端和服务器都在同一台机器上运行,通过 localhost 连接(127.0.0.1)

下面提供了两种客户端类型的示例 C++ 代码。

// Client: ipv6

#include <format>
#include <print>
#include <format>
#include <cstring>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>


int main(int argc, char* argv[]) {

    const auto PORT = 7778;

    const auto socket_fd = socket(AF_INET6, SOCK_STREAM, 0);

    in6_addr server_sin6_address;
    std::memset(&server_sin6_address, 0, sizeof(server_sin6_address));
    inet_pton(AF_INET6, "::1", &server_sin6_address);

    sockaddr_storage server_address;
    std::memset(&server_address, 0, sizeof(server_address));

    server_address.ss_family = AF_INET6;
    sockaddr_storage *p_server_address = &server_address;
    sockaddr_in6 *p_server_address_in6 = reinterpret_cast<sockaddr_in6*>(p_server_address);
    p_server_address_in6->sin6_family = AF_INET6; // why repeat?
    p_server_address_in6->sin6_port = htons(PORT);
    p_server_address_in6->sin6_flowinfo = 0; // not used?
    p_server_address_in6->sin6_addr = server_sin6_address;
    p_server_address_in6->sin6_scope_id = 0; // not used?

    const auto connect_result = connect(socket_fd, reinterpret_cast<sockaddr*>(&server_address), sizeof(server_address));

    const char* const buffer = "hello world ipv6";
    const auto buffer_length = strlen(buffer) + 1;
    send(socket_fd, buffer, buffer_length, 0);

    close(socket_fd);

    return 0;
}
// Client: ipv4

#include <format>
#include <print>
#include <format>
#include <cstring>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>


int main(int argc, char* argv[]) {

    const auto PORT = 7778;

    const auto socket_fd = socket(AF_INET, SOCK_STREAM, 0);

    in_addr server_sin_address;
    std::memset(&server_sin_address, 0, sizeof(server_sin_address));
    inet_pton(AF_INET, "127.0.0.1", &server_sin_address);

    sockaddr_storage server_address;
    std::memset(&server_address, 0, sizeof(server_address));

    server_address.ss_family = AF_INET;
    sockaddr_storage *p_server_address = &server_address;
    sockaddr_in *p_server_address_in = reinterpret_cast<sockaddr_in*>(p_server_address);
    p_server_address_in->sin_family = AF_INET; // why repeat?
    p_server_address_in->sin_port = htons(PORT);
    p_server_address_in->sin_addr = server_sin_address;
    //p_server_address_in->sin_zero = 0; // not used?

    const auto connect_result = connect(socket_fd, reinterpret_cast<sockaddr*>(&server_address), sizeof(server_address));

    const char* const buffer = "hello world ipv4";
    const auto buffer_length = strlen(buffer) + 1;
    const auto send_result = send(socket_fd, buffer, buffer_length, 0);

    close(socket_fd);
    std::println("Server quit");

    return 0;
}

也许这是 IPv4 客户端实现中的一个错误,但到目前为止我还没有发现任何看起来明显不正确的东西。

到 ipv6 目标的 ipv4 连接是否会以某种方式由操作系统自动升级?这似乎是一种非常奇怪的行为。

c++
  • 1 个回答
  • 50 Views
Martin Hope
user2138149
Asked: 2025-01-20 22:17:16 +0800 CST

如何将文件读入矢量?

  • 5

以下代码可以在 Julia REPL 中运行,展示了如何将向量的内容写入磁盘。

v = rand(Int64, 1000000)
ofile = open("example_vector.bin", "w")
write(ofile, v)
close(ofile)

反向操作大概也是可能的,但我无法找出正确的语法。

ifile = open("example_vector.bin", "r")

v2 = Vector{Int64}(undef, 1000000)
read(ifile, v) # this is not valid, perhaps unsurprisingly

# I tried a few other things which I thought might work, but none did
read(ifile, Vector{Int64}, 1000000)
read(ifile, Vector{Int64, 1000000})
read(ifile, ::Type{Vector{Int64}}, 1000000)

我已经尝试过以下事情:

  • 在网上搜索解决方案
  • 询问 ChatGPT(不出所料,它编造了一个不存在的函数调用)
  • 阅读在 REPL 中read使用该模式的文档?

我想要避免的是必须进行 100 万次函数调用来read单独读取向量的每个元素,这可能会导致性能不佳。

julia
  • 2 个回答
  • 36 Views
Martin Hope
user2138149
Asked: 2025-01-19 17:36:44 +0800 CST

Dockerfile 设置 ENV PATH 导致主机 PATH 的值在容器内使用

  • 4

$PATH我对Docker 容器内环境变量的行为有些困惑。

  • 我正在尝试将 $PATH 变量设置为/kdb/bin,加上一些其他值。
  • 相反,变量的值$PATH似乎设置为与 Docker 容器主机系统相同的值

echo $PATH主机上的值为:

$ echo $PATH
/usr/local/bin:/usr/bin:/bin

(另外还有一些我为了简洁而省略的内容。)

这是我的Dockerfile:

FROM ubuntu:24.04
WORKDIR /kdb
ENV QHOME=/kdb
ENV PATH="${QHOME}/bin:${QHOME}:$PATH"
ENV QLIC=/kdb/kc.lic
COPY ./q q
COPY ./bin bin
COPY ./src src
CMD ["/bin/bash", "-c", "sleep infinity"]

和docker-compose.yml

services:
    kdb:
        container_name: kdb
        build: .
        command: echo $PATH
        ports:
            - 5000:5000

docker-compose.yml我已将中的默认命令设置为echo $PATH,以便的值PATH将显示在日志中。

docker logs表示容器内正在使用来自主机PATH的相同值。容器变量不包含/kdb/bin或/kdb。

这是为什么呢?

docker
  • 1 个回答
  • 36 Views
Martin Hope
user2138149
Asked: 2025-01-01 01:03:04 +0800 CST

在 Julia 中构建命名元组的两种语法形式有什么区别?

  • 7

Julia 有两种构造命名元组的语法。

第一个语法使用括号内的键值对,没有分号。

named_tuple = (a=1, b=2, c=3)

语法的第二种形式使用初始分号。

named_tuple = (; a=1, b=2, c=3)

据我从文档中了解,两种形式都会产生相同的结果。(一个NamedTuple对象。)

以下两种形式看上去并没有什么区别。

julia> tuple1 = (a=1, b=2, c=3)
(a = 1, b = 2, c = 3)

julia> typeof(tuple1)
@NamedTuple{a::Int64, b::Int64, c::Int64}

julia> tuple2 = (; a=1, b=2, c=3)
(a = 1, b = 2, c = 3)

julia> typeof(tuple2)
@NamedTuple{a::Int64, b::Int64, c::Int64}

似乎可以NamedTuple通过一系列对来创建,但只有包含分号时才可以。

换句话说,此语法有效并产生预期结果

julia> tuple3 = (; :a=>1, :b=>2, :c=>3)
(a = 1, b = 2, c = 3)

julia> typeof(tuple3)
@NamedTuple{a::Int64, b::Int64, c::Int64}

另一方面,以下情况并不

julia> tuple4 = (:a=>1, :b=>2, :c=>3)
(:a => 1, :b => 2, :c => 3)

julia> typeof(tuple4)
Tuple{Pair{Symbol, Int64}, Pair{Symbol, Int64}, Pair{Symbol, Int64}}

这会产生一个Tuple,Pair而不是NamedTuple。

每种形式的预期用途是什么,或者有两种不同形式的原因是什么?

julia
  • 1 个回答
  • 31 Views
Martin Hope
user2138149
Asked: 2024-12-28 22:36:53 +0800 CST

如何在 Rust 中与作用域线程共享布尔标志?

  • 7

我正在尝试使用布尔标志来表示线程应该退出。但是,目前我的代码违反了借用检查器规则。我理解它为什么违反这些规则,但我不知道最合适的设计是什么以及如何解决问题。

fn long_running(exit_flag: &bool) {

    loop {
        std::thread::sleep(std::time::Duration::from_secs(10));

        if *exit_flag {
            break;
        }
    }
}

fn main() {

    let mut exit_flag = false;
    std::thread::scope(
        |scope| {
            let handle = scope.spawn(
                || {
                    long_running(&exit_flag); # (1)
                }
            );

            exit_flag = true; # (2)

            // terminate the consumer poll loop
            handle.join().expect("failed to join thread");
        }
    );
}

问题涉及标有# (1)和 的行# (2)。

  • # (1):引用exit_flag自
  • # (2):在引用仍被借用时尝试改变底层变量

由于借用检查规则,这是不允许的。

  • 解决该问题的一个方法可能是堆分配标志,并使用它在两个线程之间共享数据。
  • 但是,使用的目的std::thread::scope是允许启动一个可以从父(主)线程的堆栈访问局部变量的线程。

顺便说一下,这个想法是从这个帖子里得到的

  • 如何将堆栈变量的引用传递给线程?
multithreading
  • 1 个回答
  • 58 Views
Martin Hope
user2138149
Asked: 2024-12-26 23:03:21 +0800 CST

如何在 Rust 中将 JSON 输入反序列化为通用数据结构?

  • 5

大多数示例展示了使用 Rust 对 JSON 进行反序列化,并serde_json使用定义的展示了反序列化为已知结构格式struct。

是否可以将具有未知结构的 JSON 文档反序列化为可以处理这种结构变化的通用 Rust 数据类型?

例如,我尝试过这样的事情

let filename = "example.json";
let maybe_ifile = std::fs::File::open(filename);

match maybe_ifile {
    Ok(ifile) => {
        let maybe_json_data = serde_json::from_reader::<_, BTreeMap<String, String>>(ifile);

        match maybe_json_data {
            Ok(json_data) => {
                println!("{json_data:?}");
            }

            Err(error) => {
                panic!("{error}")
            }
        }
    }

    Err(error) => {
        panic!("{error}");
    }
}

如果 JSON 文档的结构为键值字符串对,则此方法有效,但对于更通用的结构则无效,因此显然使用BTreeMap<String, String>这里的方法不是正确的方法。

我想要实现的是使用运行时/某种动态类型的灵活性。

在其他语言中这也是可能的,所以我认为 Rust 中有一个相当简单的解决方案,我只是不知道这是什么。

json
  • 1 个回答
  • 35 Views
Martin Hope
user2138149
Asked: 2024-11-02 16:59:02 +0800 CST

如何在 Julia 中合并字典?

  • 4

我想在 Julia 中编写一个合并两个字典的函数。

function merge(left::Dict, right::Dict)::Dict

语义如下:

  • 输入left为right
  • left和都right拥有其数据的所有权,这意味着它们将在函数调用后被修改,并且不应对它们包含的数据做出任何保证
  • 返回值包含两个字典的数据
  • 如果任何键同时存在于两者中left,并且right值left保持不变

以下是关于如何解决此问题的一些初步想法。(这是带有注释的伪代码,而不是可以实际编译的代码。)

function mergeDict(left::Dict, right::Dict)::Dict

    # create a new dictionary from `left`
    return_value = left

    # move data from `right` to `left`, "no-clobber"
    for k, v in pop_next!(right)
    # the function `pop_next!` does not exist, no iterator-like `pop!`

    for k in keys(right)
        v = pop!(right, k)
        # does this work as expected? destructive operation while reading keys?
        # `keys()` returns an *iterator*, not a collection! (?)

        if !haskey(left, k)
            push!(left, k, v) # no `push!` function
            left[k] = v # this works instead
        end
    end
    
    # `left` and `right` are not pointers, but "copy-by-value references"
    # just as in Python, so this doesn't work
    left = nothing
    right = nothing

    # we want to invalidate the data, how to do that?
    # this also won't work because `left` references the same data
    # structure as `return_value`
    clear(left)
    clear(right)
end

您可以看到,我尝试编写手动实现。我确信 Julia 会有一些有用的函数作为标准库的一部分来实现这一点,但是由于我是 Julia 新手,我不知道这些函数是什么。

我找到了函数merge、和mergewith,然而这些函数似乎都不具备上面描述的语义。merge!mergewith!

dictionary
  • 1 个回答
  • 27 Views
Martin Hope
user2138149
Asked: 2024-11-02 00:42:17 +0800 CST

如何将磁盘上的文件与磁盘上不存在的不同分支的文件进行比较

  • 5

我想对磁盘上存在的文件和由于我移动而不再存在的文件进行比较操作。

情况是这样的。

  • 我有一个存在于文件夹中的文件。我们把它命名为./src/A.txt。
  • 我移至A.txt新文件夹。它现在名为./doc/A.txt。
  • 我编辑了./doc/A.txt。

我现在想与分支上存在的./doc/A.txt状态进行比较。当然,这个文件实际上并不存在于当前工作目录中。./src/A.txtorigin/main

我认为实现此目的的一种可能方法是执行以下操作:

  • git checkout origin/main ./src/A.txt
  • git diff ./src/A.txt ./doc/A.txt

(编辑:不 - 这不起作用。请使用diff ./src/A.txt ./doc/A.txt。)

有没有办法“直接”做到这一点?

也许类似

git diff ./src/A.txt@origin/main ./doc/A.txt
git
  • 1 个回答
  • 38 Views
Martin Hope
user2138149
Asked: 2024-10-28 23:32:24 +0800 CST

Julialang 中的 `:` 和 `quote` 表达式有什么区别?

  • 7

我不完全理解Julia 中的quote ... end和:( ... )表达式之间有什么区别。

看起来唯一的区别好像是前者(quote)引入了额外的注释行。

  • 差异就这么简单吗,或者还有更多其他的差异?
  • 这些注释行的目的是什么?它们有什么作用?或者换句话说,为什么你会使用其中一个而不是另一个?

以下是一些例子

julia> :(2+2)
:(2 + 2)

julia> e1=:(2+2)
:(2 + 2)

julia> e1
:(2 + 2)

julia> eval(e1)
4
julia> quote
           2+2
       end
quote
    #= REPL[2]:2 =#
    2 + 2
end

julia> e2=quote
           2+2
       end
quote
    #= REPL[5]:2 =#
    2 + 2
end

julia> e2
quote
    #= REPL[5]:2 =#
    2 + 2
end

julia> eval(e2)
4

我找到了这本维基百科,但它只说

引用表达式的每一行都添加了有用的行号

(指与……quote相比:)。

关键字表达式的文档页面也没有说太多。

与其他引用方式 :( ... ) 不同,此形式将 QuoteNode 元素引入表达式树,直接操作树时必须考虑到这一点。

这意味着什么?

julia
  • 1 个回答
  • 34 Views
Martin Hope
FreelanceConsultant
Asked: 2024-07-05 21:50:03 +0800 CST

如何使用索引从 Pandas DataFrame 中选择行?

  • 4

我正在尝试使用整数索引值从 Pandas DataFrame 中选择行。

这不起作用,并且我获得了索引错误。

  • 这表明,按索引选择行隐式地会导致reset_index()被调用,尽管我可能错了
  • 下面的例子解释了为什么我观察到的行为表明了这一点
import pandas

data = {
    'number': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'fruit': 3 * ['apple'] + 3 * ['pear'] + 2 * ['banana'] + ['pear'] + ['apple'],
    'color': 3 * ['red', 'green', 'blue'] + ['red'],
    'letter': 5 * ['A', 'B'],
}
df = pandas.DataFrame(data)
df

Pandas 数据框

df_selected = df[df['fruit'] == 'pear']
df_selected

Pandas 数据框

df_selected.index
Index([3, 4, 5, 8], dtype='int64')

这当然表明我有一个 DataFrame,其索引包含值 3、4、5 和 8。

我现在想使用整数索引选择 DataFrame 中从第一次出现“pear”到最后一次出现的所有行:

我认为使用以下语法应该可以实现:

FIRST = 3
LAST = 8
df_selected[FIRST:LAST+1]

但我错了:

Pandas 数据框

  • 打印时(显示 DataFrame 到stdout或 Jupyter Notebook Cell)索引显示值3, 4, 5, 8。
  • 当使用语法df_selected[A:B]或df_selected.iloc[A:B]整数参数按索引进行选择时A,它们B被解释为df_selected.reset_index()已被调用
  • 我这样说是因为调用reset_index()会产生以下输出

Pandas 数据框

这意味着按索引选择时使用的正确范围是df_selected.iloc[0:3+1]

我知道这是一个非常基本的问题,但我希望有人可以给我指出正确的方向,让我理解为什么会出现这样的行为,如果有特殊的原因的话。

pandas
  • 1 个回答
  • 37 Views
Martin Hope
FreelanceConsultant
Asked: 2024-02-12 01:49:56 +0800 CST

如何在Python中对字典进行分区?

  • 5

许多语言都提供标准库,其中提供字典或二叉树映射类型。许多这些数据结构实现都提供了根据某些条件将数据结构拆分为一对数据结构的功能。

这称为分区操作。Rust 称之为“分裂”。C++map类型具有用于与键进行比较的“下限”和“上限”操作。标准库还提供了存在于std::algorithm.

我看不到在 Python 中执行此操作的理想方法。我设法想出了一种手动方法来做到这一点,但我真的不喜欢这段代码,因为它没有将 adict分成两部分,而是将其中的一部分拆分,然后再将其拆分为另一部分,从而导致脆弱(和重复)的代码。

map = {
   ...
}

map_part_1 = {
    key: value for key, value in map.items() if <condition>
}

map_part_2 = {
    key: value for key, value in map.items() if not <condition>
}

不太好,对吧?有没有更好的办法?

python
  • 3 个回答
  • 121 Views
Martin Hope
FreelanceConsultant
Asked: 2024-01-03 01:32:31 +0800 CST

如何防止 matplotlib 在轴上绘制“天数”

  • 6

使用 matplotlib 绘制一些数据时,我发现一个有点烦人的问题。

如下面的示例输出所示,x 轴的格式有点出乎意料。

标签是(例如)04 12:30。是该04月中的某一天。

提供代码和数据来重现该图,并附加在该问题的末尾。

为什么 x 轴的格式是这样的?我能做些什么来“修复”它?(我不希望显示该月的某一天,而且我特别不希望将其格式设置为“04”。)

matplotlib 图形

代码

运行代码:python3 example.py

# example.py

import matplotlib.pyplot as plt
import pandas

df = pandas.read_json('data.json')

print(df.head())

fig, ax1 = plt.subplots(figsize=(12, 8))
ax1.plot(df['column_name'], label='My data')
ax1.set_xlabel('Timestamp')
ax1.set_ylabel('Value')
ax1.grid(True)
ax1.legend()

plt.title('Example')
plt.tight_layout()
plt.savefig('example.png')

数据

将此文件另存为data.json

{"column_name":{"1649073600000":174.79,"1649073660000":174.8,"1649073720000":174.79,"1649073780000":174.76,"1649073840000":174.69,"1649073900000":174.7,"1649073960000":174.69,"1649074020000":174.65,"1649074140000":174.67,"1649074200000":174.7,"1649074260000":174.74,"1649074320000":174.65,"1649074380000":174.69,"1649074440000":174.65,"1649074500000":174.7,"1649074560000":174.74,"1649074680000":174.72,"1649074740000":174.7,"1649074860000":174.7,"1649074920000":174.71,"1649074980000":174.75,"1649075040000":174.76,"1649075100000":174.73,"1649075160000":174.76,"1649075220000":174.7,"1649075280000":174.66,"1649075340000":174.61,"1649075400000":174.63,"1649075460000":174.65,"1649075520000":174.7,"1649075580000":174.69,"1649075640000":174.63,"1649075760000":174.66,"1649075820000":174.63,"1649075880000":174.58,"1649075940000":174.5,"1649076000000":174.52,"1649076060000":174.55,"1649076120000":174.55,"1649076180000":174.54,"1649076240000":174.48,"1649076300000":174.45,"1649076360000":174.38,"1649076420000":174.22,"1649076480000":174.21,"1649076540000":174.15,"1649076660000":174.25,"1649076720000":174.3,"1649076780000":174.28,"1649076840000":174.26,"1649076900000":174.25,"1649076960000":174.23,"1649077020000":174.21,"1649077080000":174.25,"1649077140000":174.26,"1649077200000":174.27}}
python
  • 1 个回答
  • 31 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve