<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>RGC Blogs</title>
    <description></description>
    
    <link>https://rgc-dev.beehiiv.com/</link>
    <atom:link href="https://rss.beehiiv.com/feeds/4acUwW1FSC.xml" rel="self"/>
    
    <lastBuildDate>Sun, 25 Oct 2026 03:44:20 +0000</lastBuildDate>
    <pubDate>Sat, 24 Oct 2026 17:34:48 +0000</pubDate>
    <atom:published>2026-10-24T17:34:48Z</atom:published>
    <atom:updated>2026-10-25T03:44:20Z</atom:updated>
    
      <category>Programming</category>
      <category>Artificial Intelligence</category>
      <category>Technology</category>
    <copyright>Copyright 2026, RGC Blogs</copyright>
    
    <image>
      <url>https://media.beehiiv.com/cdn-cgi/image/fit=scale-down,format=auto,onerror=redirect,quality=80/uploads/publication/logo/9b429155-7f13-4cb8-979a-4eb10bd390af/logo.png</url>
      <title>RGC Blogs</title>
      <link>https://rgc-dev.beehiiv.com/</link>
    </image>
    
    <docs>https://www.rssboard.org/rss-specification</docs>
    <generator>beehiiv</generator>
    <language>en-us</language>
    <webMaster>support@beehiiv.com (Beehiiv Support)</webMaster>

      <item>
  <title>RGC 网络编程入门:TCP、UDP 与 HTTP 客户端</title>
  <description>RGC 标准库提供同步 TCP / UDP / HTTP / HTTPS 网络能力。这篇教程从 TCP 回环示例开始,带你掌握 net、udp、http、tls 模块,最后用一个自包含的 HTTP 请求工具串联全部知识。</description>
  <link>https://rgc-dev.beehiiv.com/p/new-post-694c</link>
  <guid isPermaLink="true">https://rgc-dev.beehiiv.com/p/new-post-694c</guid>
  <pubDate>Sat, 24 Oct 2026 17:34:48 +0000</pubDate>
  <atom:published>2026-10-24T17:34:48Z</atom:published>
    <category><![CDATA[Networking]]></category>
    <category><![CDATA[Stdlib]]></category>
    <category><![CDATA[Tutorial]]></category>
  <content:encoded><![CDATA[
    <div class='beehiiv'><style>
  .bh__table, .bh__table_header, .bh__table_cell { border: 1px solid #C0C0C0; }
  .bh__table_cell { padding: 5px; background-color: #FFFFFF; }
  .bh__table_cell p { color: #2D2D2D; font-family: 'Helvetica',Arial,sans-serif !important; overflow-wrap: break-word; }
  .bh__table_header { padding: 5px; background-color:#F1F1F1; }
  .bh__table_header p { color: #2A2A2A; font-family:'Trebuchet MS','Lucida Grande',Tahoma,sans-serif !important; overflow-wrap: break-word; }
</style><div class='beehiiv__body'><div class="custom_html"><p>RGC 标准库提供了<strong>同步</strong>的网络能力：TCP / UDP / HTTP / HTTPS，全部以源码模块形式放在 <code>lib/</code> 下，用 RGC 自身封装：</p><table><thead><tr><th>模块</th><th>用途</th></tr></thead><tbody><tr><td><code>net</code></td><td>同步 TCP（连接/监听/收发/超时/Unix 域套接字）</td></tr><tr><td><code>udp</code></td><td>数据报（发送/接收/IPv6/二进制/超时）</td></tr><tr><td><code>http</code></td><td>HTTP/1.1 客户端（含 HTTPS、重定向、gzip、Cookie、代理、连接池）</td></tr><tr><td><code>https</code></td><td>HTTPS 兼容层（<code>http</code> 已原生支持 <code>https://</code>）</td></tr><tr><td><code>tls</code></td><td>低层 TLS 连接（自定义收发协议、mTLS 客户端证书）</td></tr><tr><td><code>bytes</code></td><td>二进制安全的字节缓冲（网络收发辅助）</td></tr></tbody></table><p>底层通过 <code>extern def</code> 直接调用 libc socket / OpenSSL / zlib，链接参数由编译器按符号引用自动追加（TLS 追加 <code>-lssl -lcrypto</code>，压缩追加 <code>-lz</code>），不需要手动配置链接器。</p><p>一个贯穿全篇的设计：网络操作的结果用 <code>ok: bool</code> + <code>error: str</code> 的包装类返回，<strong>失败不 panic、不抛异常</strong>。连接被拒绝、解析失败、端口越界都会得到一个 <code>ok=False</code> 的结果，你负责检查并处理。</p><h2>1. 准备</h2><p>编译器会自动在标准库目录（<code>lib/</code>）查找模块，直接编译运行即可：</p><pre><code class="language-bash">rgc main.rg -o prog
./prog
</code></pre><p>本篇所有示例都在本仓库用 <code>src/build/rgc3</code> 编译运行验证过，可直接复制。</p><h2>2. TCP：连接与监听</h2><h3>2.1 一个完整的 TCP 回环示例</h3><p>下面这个程序单进程内完成「监听 → 连接 → 接受 → 双向收发 → 关闭」全流程。<code>listen_on</code> 使用端口 <code>0</code> 时，内核会分配一个临时端口：</p><pre><code class="language-python">import net

def main() -&gt; int {
    # 1) 监听：端口 0 让内核分配临时端口
    l = net.listen_on(&quot;127.0.0.1&quot;, 0)
    if not l.ok {
        print(&quot;listen failed:&quot;, l.error)
        return 1
    }
    listener = l.listener
    port = listener.local_port()
    print(&quot;listening on port&quot;, port)

    # 2) 客户端连接（backlog 让连接先排队）
    c = net.connect_to(&quot;127.0.0.1&quot;, port)
    if not c.ok {
        print(&quot;connect failed:&quot;, c.error)
        listener.close()
        return 1
    }
    client = c.stream

    # 3) 服务器接受连接
    a = listener.accept()
    if not a.ok {
        print(&quot;accept failed:&quot;, a.error)
        client.close()
        listener.close()
        return 1
    }
    server = a.stream

    # 4) 双向收发
    client.send(&quot;ping&quot;)
    r1 = server.recv(64)
    print(&quot;server got:&quot;, r1.value)     # ping

    server.send(&quot;pong&quot;)
    r2 = client.recv(64)
    print(&quot;client got:&quot;, r2.value)     # pong

    # 5) 关闭：对端会读到 EOF（ok=True, value=&quot;&quot;）
    client.close()
    eof = server.recv(16)
    print(&quot;eof:&quot;, eof.ok, eof.value.len())   # True 0

    server.close()
    listener.close()
    return 0
}
</code></pre><p>运行输出：</p><pre><code>listening on port 43727
server got: ping
client got: pong
eof: True 0
</code></pre><p>几个要点：</p><ul><li><code>send</code> 阻塞直到全部字节写出，返回实际发送字节数；</li><li><code>recv(max)</code> 最多读取 <code>max</code> 字节；对端关闭（EOF）时返回 <code>ok=True, value=&quot;&quot;</code>；</li><li>真实错误（连接拒绝、解析失败、超时）返回 <code>ok=False</code> + <code>error</code> 文本；</li><li><code>close()</code> 重复调用安全，不会崩溃。</li></ul><h3>2.2 TCP API 一览</h3><table><thead><tr><th>API</th><th>签名</th><th>说明</th></tr></thead><tbody><tr><td>连接</td><td><code>net.connect(addr: str) -&gt; TcpConnect</code></td><td>地址形如 <code>&quot;host:port&quot;</code>，按最后一个 <code>:</code> 切分</td></tr><tr><td>连接</td><td><code>net.connect_to(host: str, port: int) -&gt; TcpConnect</code></td><td>结构化形式，端口 1–65535</td></tr><tr><td>超时</td><td><code>net.connect_timeout(addr, ms)</code> / <code>connect_to_timeout(host, port, ms)</code></td><td>连接超时（毫秒，<code>0</code> 阻塞）</td></tr><tr><td>监听</td><td><code>net.listen(addr)</code> / <code>net.listen_on(host, port)</code></td><td><code>SO_REUSEADDR</code>，backlog 128；端口 <code>0</code> 为临时端口</td></tr><tr><td>解析</td><td><code>net.resolve(host) -&gt; List[str]</code></td><td><code>getaddrinfo</code> 返回的地址列表（IPv4/IPv6）</td></tr><tr><td>发送</td><td><code>TcpStream.send(data: str) -&gt; int</code></td><td>阻塞写完全部字节</td></tr><tr><td>发送</td><td><code>TcpStream.send_bytes(data: @Bytes) -&gt; int</code></td><td>二进制安全（显式长度）</td></tr><tr><td>接收</td><td><code>TcpStream.recv(max) -&gt; TcpRecv</code></td><td>最多 <code>max</code> 字节；EOF 返回空串</td></tr><tr><td>接收</td><td><code>TcpStream.recv_bytes(max) -&gt; TcpRecvBytes</code></td><td>二进制安全</td></tr><tr><td>超时</td><td><code>TcpStream.set_timeout(ms)</code></td><td>设置后续收发超时；<code>0</code> 恢复阻塞</td></tr><tr><td>半关闭</td><td><code>TcpStream.shutdown_write()</code></td><td>发送 FIN，仍可接收</td></tr><tr><td>地址</td><td><code>TcpStream.local_port()</code> / <code>peer_host()</code> / <code>peer_port()</code></td><td>本端/对端地址信息</td></tr><tr><td>接受</td><td><code>TcpListener.accept()</code> / <code>accept_timeout(ms)</code></td><td>阻塞等待连接</td></tr><tr><td>端口</td><td><code>TcpListener.local_port() -&gt; int</code></td><td>实际监听端口</td></tr><tr><td>Unix</td><td><code>net.connect_unix(path)</code> / <code>net.listen_unix(path)</code></td><td>Unix 域套接字，<code>@name</code> 表示抽象地址空间</td></tr></tbody></table><p>结果包装类：<code>TcpConnect</code> / <code>TcpListen</code> / <code>TcpAccept</code> / <code>TcpRecv</code>，都带 <code>ok: bool</code> 与 <code>error: str</code> 字段（失败时 <code>stream.fd == -1</code>）。</p><h2>3. UDP：数据报</h2><p>UDP 是无连接的，<code>udp.open</code> 绑定一个本地端口，<code>send_to</code> / <code>recv_from</code> 每次收发一个<strong>数据报</strong>：</p><pre><code class="language-python">import bytes
import udp

def main() -&gt; int {
    a = udp.open(&quot;127.0.0.1:0&quot;)
    b = udp.open(&quot;127.0.0.1:0&quot;)
    if not a.ok or not b.ok {
        print(&quot;bind failed&quot;)
        return 1
    }
    s1 = a.sock
    s2 = b.sock
    port2 = s2.local_port()

    # 发送数据报
    r = s1.send_to(&quot;ping&quot;, &quot;127.0.0.1&quot;, port2)
    print(&quot;sent:&quot;, r.ok, r.sent)                     # True 4
    r2 = s2.recv_from(64)
    print(&quot;got:&quot;, r2.data, r2.host, r2.port == s1.local_port())

    # 数据报边界：两次发送 -&gt; 两次接收
    s1.send_to(&quot;one&quot;, &quot;127.0.0.1&quot;, port2)
    s1.send_to(&quot;two&quot;, &quot;127.0.0.1&quot;, port2)
    print(&quot;dgram:&quot;, s2.recv_from(64).data, s2.recv_from(64).data)   # one two

    # 二进制安全：data_bytes 保留全部字节
    payload = bytes.bytes_new(2)
    payload.push(0)
    payload.push(255)
    s1.send_bytes(payload, &quot;127.0.0.1&quot;, port2)
    r3 = s2.recv_from(16)
    print(&quot;binary:&quot;, r3.data_bytes.len, r3.data_bytes.get(0), r3.data_bytes.get(1))

    # 读超时
    s2.set_timeout(100)
    r4 = s2.recv_from(16)
    print(&quot;timeout:&quot;, r4.ok, r4.error)              # False timeout

    s1.close()
    s2.close()
    return 0
}
</code></pre><p>运行输出：</p><pre><code>sent: True 4
got: ping 127.0.0.1 True
dgram: one two
binary: 2 0 255
timeout: False timeout
</code></pre><p>要点：</p><ul><li>一次 <code>recv_from</code> 对应一个数据报，不会与相邻数据报拼接；</li><li><code>data</code> 按 C 字符串处理（遇 NUL 截断）；需要二进制数据用 <code>data_bytes</code> 和 <code>send_bytes</code>；</li><li><code>set_timeout(ms)</code> 后超时返回 <code>ok=False, error=&quot;timeout&quot;</code>，<code>0</code> 恢复阻塞；</li><li>IPv6 直接 <code>udp.open_on(&quot;::1&quot;, 0)</code>；主机名自动解析（<code>localhost</code> 等）。</li></ul><h2>4. HTTP 客户端</h2><h3>4.1 一次性请求</h3><p><code>import http</code> 提供模块级函数，一次调用完成请求：</p><pre><code class="language-python">import http

def main() {
    r = http.get(&quot;http://127.0.0.1:8080/hello&quot;)
    if not r.ok {
        print(&quot;request failed:&quot;, r.error)          # 网络/证书/限额错误
        return
    }
    res = r.response
    print(&quot;status:&quot;, res.status)                   # 200
    print(&quot;type:&quot;, http.header(@res, &quot;Content-Type&quot;))
    print(&quot;body:&quot;, res.body)
}
</code></pre><ul><li><code>http.get(url)</code> / <code>http.post(url, body)</code> / <code>http.request(method, url, body)</code>；</li><li>响应结构 <code>HttpResponse</code>：<code>status</code>、<code>version</code>、<code>headers</code>、<code>body</code>、<code>body_bytes</code>、<code>url</code>（重定向后的最终地址）；</li><li><code>http.header(@res, &quot;Content-Type&quot;)</code> 大小写不敏感地查响应头，未找到返回 <code>&quot;&quot;</code>；</li><li><code>body</code> 是已解压的文本（<code>strlen</code> 语义），二进制内容用 <code>body_bytes</code>；</li><li>默认自动跟随 3xx 重定向，自动解压 <code>gzip</code> / <code>deflate</code>。</li></ul><h3>4.2 复用连接的客户端</h3><p>需要 keep-alive、Cookie、自定义头、代理或限额时，使用 <code>http.new_client()</code>：</p><pre><code class="language-python">import http

def main() {
    c = http.new_client()
    c.add_header(&quot;X-Token&quot;, &quot;secret&quot;)          # 每次请求附加
    c.timeout_ms = 5000                          # 读超时
    c.max_body = 1 &lt;&lt; 20                        # 正文上限 1 MiB

    a = c.get(&quot;http://127.0.0.1:8080/a&quot;)       # 同一 keep-alive 连接
    b = c.post(&quot;http://127.0.0.1:8080/b&quot;, &quot;data&quot;)
    print(a.response.status, b.response.status)
    c.close()
}
</code></pre><p>常用配置字段：</p><table><thead><tr><th>字段</th><th>默认</th><th>说明</th></tr></thead><tbody><tr><td><code>timeout_ms</code></td><td>30000</td><td>单次请求读超时</td></tr><tr><td><code>connect_timeout_ms</code></td><td>10000</td><td>TCP/TLS 连接与握手超时</td></tr><tr><td><code>max_redirects</code></td><td>10</td><td>超过返回 <code>too many redirects</code></td></tr><tr><td><code>max_body</code></td><td>32 MiB</td><td>解压前/后的正文上限</td></tr><tr><td><code>max_header</code></td><td>64 KiB</td><td>单个响应头上限</td></tr><tr><td><code>proxy</code></td><td><code>&quot;&quot;</code></td><td>HTTP 代理（HTTPS 走 CONNECT 隧道）</td></tr><tr><td><code>verify_tls</code></td><td>True</td><td>是否校验证书链与主机名</td></tr><tr><td><code>keep_alive</code></td><td>True</td><td>是否复用连接</td></tr><tr><td><code>follow_redirects</code></td><td>True</td><td>是否自动跟随 3xx</td></tr><tr><td><code>compress_request</code></td><td>False</td><td>请求体 gzip 压缩</td></tr><tr><td><code>headers</code> / <code>cookies</code></td><td><code>[]</code></td><td>附加头 / Cookie 罐</td></tr></tbody></table><h3>4.3 查询串编解码</h3><pre><code class="language-python">pairs = List[str]()
pairs.push(&quot;q=a b&quot;)
pairs.push(&quot;x=1&quot;)
print(http.encode_query(pairs))        # q=a%20b&x=1

dq = http.decode_query(&quot;q=hello+world&x=%E4%BD%A0&quot;)
print(dq.get(0), dq.get(1))             # q=hello world x=你
</code></pre><h3>4.4 异步请求</h3><p><code>async def</code> 函数在调用点派生线程，返回 <code>Task[T]</code>，配合内建 <code>asyncio</code> 汇合：</p><pre><code class="language-python">import asyncio
import http

def main() -&gt; int {
    tasks = List[Task[HttpResult]]()
    tasks.push(http.get_async(&quot;http://127.0.0.1:8080/a&quot;))
    tasks.push(http.get_async(&quot;http://127.0.0.1:8080/b&quot;))
    rs = asyncio.run(asyncio.gather(tasks))
    print(rs.len(), rs.get(0).ok, rs.get(1).ok)
    return 0
}
</code></pre><h2>5. HTTPS 与 TLS</h2><p><code>http</code> 模块原生支持 <code>https://</code>（默认校验证书链与主机名），无需额外配置。需要跳过证书校验（本地自签名服务）时用 <code>https</code> 兼容层：</p><pre><code class="language-python">import https

def main() {
    r = https.get(&quot;https://example.com/&quot;)
    if r.ok {
        print(r.response.status)
    } else {
        print(&quot;request failed:&quot;, r.error)      # 证书/网络错误
    }

    local = https.get_insecure(&quot;https://127.0.0.1:8443/&quot;)
    print(local.ok)                              # 跳过证书校验，仅供本地测试
}
</code></pre><p>需要低层 TLS 时用 <code>tls.connect</code>：</p><pre><code class="language-python">import tls

def main() {
    c = tls.connect(&quot;example.com&quot;, 443, 10000, True)   # 超时 10s，校验证书
    if c.ok {
        s = c.conn
        s.send(&quot;GET / HTTP/1.1\r\nHost: example.com\r\n\r\n&quot;)
        print(s.recv(4096).value)
        s.close()
    }
}
</code></pre><h2>6. 实战：自包含的 HTTP 请求工具</h2><p>现在把 net 和 http 结合起来，写一个<strong>自包含</strong>的程序：<code>main</code> 在后台用 <code>--serve</code> 参数启动自己作为最小 HTTP 服务器，然后作为客户端用 <code>http.get</code> / <code>http.post</code> 请求它。这样不需要任何外部服务，单文件即可跑通。</p><pre><code class="language-python">import http
import io
import net
import os
import time

# --serve 模式：最小 HTTP 服务器（响应 3 个连接）
def serve(port_file: str) -&gt; int {
    l = net.listen_on(&quot;127.0.0.1&quot;, 0)
    if not l.ok {
        return 1
    }
    listener = l.listener
    port = listener.local_port()
    wr = io.write_file(port_file, to_string(port))
    if not wr.is_ok() {
        listener.close()
        return 1
    }

    served = 0
    while served &lt; 3 {
        a = listener.accept()
        if not a.ok {
            break
        }
        s = a.stream
        buf = &quot;&quot;
        while not buf.contains(&quot;\r\n\r\n&quot;) {
            r = s.recv(256)
            if not r.ok or r.value.len() == 0 {
                break
            }
            buf = buf + r.value
        }
        body = &quot;hello from RGC server&quot;
        resp = &quot;HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: &quot; +
               to_string(body.len()) + &quot;\r\n\r\n&quot; + body
        s.send(resp)
        s.close()
        served = served + 1
    }
    listener.close()
    return 0
}

def main() -&gt; int {
    argv = args()
    if argv.len() &gt; 2 and argv.get(1) == &quot;--serve&quot; {
        return serve(argv.get(2))
    }

    port_file = &quot;/tmp/rgc_http_demo.port&quot;
    io.remove_file(port_file)
    cmd = &quot;&#39;&quot; + argv.get(0) + &quot;&#39; --serve &#39;&quot; + port_file + &quot;&#39; &gt;/dev/null 2&gt;&1 &&quot;
    os.system(cmd)

    # 等待服务器把端口写入文件
    port = 0
    tries = 0
    while tries &lt; 200 {
        if io.exists(port_file) {
            fr = io.read_file(port_file)
            if fr.is_ok() {
                port = fr.unwrap().to_int().unwrap()
                break
            }
        }
        time.sleep(0.01)
        tries = tries + 1
    }
    if port == 0 {
        print(&quot;server did not start&quot;)
        return 1
    }
    print(&quot;server started on&quot;, port)

    base = &quot;http://127.0.0.1:&quot; + to_string(port)

    # GET：检查状态、头与正文
    r = http.get(base + &quot;/hello&quot;)
    if r.ok {
        res = r.response
        print(&quot;status:&quot;, res.status)
        print(&quot;content-type:&quot;, http.header(@res, &quot;Content-Type&quot;))
        print(&quot;body:&quot;, res.body)
    } else {
        print(&quot;request failed:&quot;, r.error)
    }

    # POST
    p = http.post(base + &quot;/echo&quot;, &quot;hello&quot;)
    print(&quot;post:&quot;, p.ok, p.response.status)

    # 查询串编码
    pairs = List[str]()
    pairs.push(&quot;q=a b&quot;)
    pairs.push(&quot;x=1&quot;)
    print(&quot;encoded:&quot;, http.encode_query(pairs))

    return 0
}
</code></pre><p>运行输出：</p><pre><code>server started on 38819
status: 200
content-type: text/plain
body: hello from RGC server
post: True 200
encoded: q=a%20b&x=1
</code></pre><p>这个例子把本篇的知识串起来了：</p><ul><li><code>net.listen_on</code> + <code>TcpListener.accept</code> 实现服务器；</li><li><code>TcpStream.recv</code> / <code>send</code> 读写原始字节；</li><li><code>io.write_file</code> / <code>io.read_file</code> / <code>io.exists</code> 在父子进程间传递端口；</li><li><code>os.system</code> 启动后台进程；</li><li><code>http.get</code> / <code>http.post</code> / <code>http.header</code> / <code>http.encode_query</code> 完成客户端请求；</li><li>每个可能失败的点都用 <code>ok</code> 判断并优雅退出，没有 panic。</li></ul><h2>7. 注意事项</h2><ul><li><strong>同步模型</strong>：网络调用是阻塞的。需要并发时用 <code>async def</code> + <code>asyncio</code>（一任务一线程），或自己派生子进程。</li><li><strong>二进制数据用 <code>Bytes</code></strong>：<code>str</code> 的 <code>len()</code> 基于 <code>strlen</code>，遇 NUL 会截断；<code>send_bytes</code> / <code>recv_bytes</code> / <code>body_bytes</code> / <code>data_bytes</code> 才是二进制安全的。</li><li><strong>字符串生命周期</strong>：接收缓冲与返回字符串为堆分配，当前无 GC，进程退出时由系统回收。</li><li><strong>错误即值</strong>：所有网络 API 通过 <code>ok/error</code> 返回失败原因，不要假设某个操作一定成功。</li><li><strong>外部依赖</strong>：TLS 需要 OpenSSL，gzip 需要 zlib；编译器检测到符号引用后自动追加链接参数。</li></ul><h2>8. 下一步</h2><ul><li>标准库规范：仓库 <code>docs/compiler/STDLIB.md</code>（网络章节含全部 API 细节与行为约定）</li><li><a href="https://rgc-lang.github.io/blog/rgc-tutorial-getting-started?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-tcp-udp-http">RGC 入门教程：从 Hello World 到成绩管理器</a></li><li><a href="https://rgc-lang.github.io/blog/rack-tutorial-getting-started?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-tcp-udp-http">rack 入门：用 RGC 包管理器构建项目</a></li><li><a href="https://rgc-lang.github.io/blog/pyrig-tutorial-getting-started?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-tcp-udp-http">pyrig 入门：把 RGC 函数变成 Python 原生扩展</a></li></ul><p>RGC 以 Apache 2.0 协议开源。欢迎在 <a href="https://github.com/lexing-2026/vscode-rgc?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-tcp-udp-http">GitHub</a> 提 Issue、贡献代码。</p></div></div><div class='beehiiv__footer'><br class='beehiiv__footer__break'><hr class='beehiiv__footer__line'><a target="_blank" class="beehiiv__footer_link" style="text-align: center;" href="https://www.beehiiv.com/powered-by?publication_logo=https%3A%2F%2Fmedia.beehiiv.com%2Fcdn-cgi%2Fimage%2Ffit%3Dscale-down%2Cformat%3Dauto%2Conerror%3Dredirect%2Cquality%3D80%2Fuploads%2Fpublication%2Flogo%2F9b429155-7f13-4cb8-979a-4eb10bd390af%2Flogo.png%3Fv%3D1792898898&publication_name=RGC+Blogs&utm_campaign=001c62a7-d1f9-4c82-9623-f68167f5726c&utm_medium=post_rss&utm_source=rgc_blogs">Powered by beehiiv</a></div></div>
  ]]></content:encoded>
</item>

      <item>
  <title>rack 入门:用 RGC 包管理器构建项目</title>
  <description>rack 是 RGC 的包管理器——项目脚手架、依赖安装与传递依赖解析、锁文件、构建运行、发布与搜索。这篇教程从发布示例包开始,带你完整走一遍项目生命周期。</description>
  <link>https://rgc-dev.beehiiv.com/p/new-post-cc53</link>
  <guid isPermaLink="true">https://rgc-dev.beehiiv.com/p/new-post-cc53</guid>
  <pubDate>Sat, 24 Oct 2026 17:34:44 +0000</pubDate>
  <atom:published>2026-10-24T17:34:44Z</atom:published>
    <category><![CDATA[Tutorial]]></category>
  <content:encoded><![CDATA[
    <div class='beehiiv'><style>
  .bh__table, .bh__table_header, .bh__table_cell { border: 1px solid #C0C0C0; }
  .bh__table_cell { padding: 5px; background-color: #FFFFFF; }
  .bh__table_cell p { color: #2D2D2D; font-family: 'Helvetica',Arial,sans-serif !important; overflow-wrap: break-word; }
  .bh__table_header { padding: 5px; background-color:#F1F1F1; }
  .bh__table_header p { color: #2A2A2A; font-family:'Trebuchet MS','Lucida Grande',Tahoma,sans-serif !important; overflow-wrap: break-word; }
</style><div class='beehiiv__body'><div class="custom_html"><p><strong>rack</strong> 是 RGC 的包管理器，用 RGC 自己编写。它管理 RGC 项目的完整生命周期：新建项目、安装依赖（含传递依赖解析与完整性校验）、锁文件、构建与运行、发布与搜索。</p><p>这篇教程从一个真实的示例包出发，带你走一遍完整流程：发布 → 新建项目 → 安装依赖 → 查看依赖树 → 构建运行 → 发布自己的包。所有命令都在仓库中验证过，可以直接复制运行。</p><h2>1. 准备</h2><p>rack 二进制在仓库 <code>rack/target/bin/rack</code>（已构建）。也可以自行构建：</p><pre><code class="language-bash">cd rack && ./tests/bootstrap.sh
# -&gt; target/bin/rack
</code></pre><p>rack 构建项目时需要调用 rgc 编译器，通过 <code>RGC</code> 环境变量指定：</p><pre><code class="language-bash">export RGC=/path/to/RGLite/build/rgc
</code></pre><p>验证：</p><pre><code class="language-bash">rack --version
# rack 0.3.0 (RGC)
</code></pre><h2>2. 发布示例包到本地注册表</h2><p>rack 使用本地注册表（默认 <code>$HOME/.rack/registry</code>）。先把仓库里两个示例包发布进去：</p><pre><code class="language-bash">cd rack/examples/mathx
rack publish

cd ../calcx
rack publish
</code></pre><p>输出：</p><pre><code>Published mathx@0.2.0 -&gt; $HOME/.rack/registry
Published calcx@0.1.0 -&gt; $HOME/.rack/registry
</code></pre><ul><li><code>mathx</code> 是一个数学工具模块，提供 <code>add</code> / <code>mul</code> / <code>fib</code> / <code>square_sum</code>；</li><li><code>calcx</code> 依赖 <code>mathx@0.2.0</code>，提供 <code>double_add</code> / <code>fib_sq</code>。</li></ul><h2>3. 新建项目</h2><pre><code class="language-bash">rack new demo && cd demo
</code></pre><p>生成：</p><pre><code>demo/
├── .gitignore   # 忽略 target/ 与 a.out
├── main.rg      # 项目入口
└── rack.toml   # 清单
</code></pre><p>默认 <code>main.rg</code>：</p><pre><code class="language-python"># demo — rack 项目入口

def main() {
    print(&quot;hello from demo&quot;)
}
</code></pre><p><code>rack.toml</code> 记录包元数据：</p><pre><code class="language-toml">[package]
name = &quot;demo&quot;
version = &quot;0.1.0&quot;
entry = &quot;main.rg&quot;
</code></pre><h2>4. 安装依赖</h2><p>把 <code>main.rg</code> 改成使用 <code>calcx</code>：</p><pre><code class="language-python">import calcx

def main() -&gt; int {
    print(double_add(2, 3))
    return 0
}
</code></pre><p>安装：</p><pre><code class="language-bash">rack install calcx
</code></pre><p>输出：</p><pre><code>  resolved calcx -&gt; calcx@0.1.0
  + calcx@0.1.0
  + mathx@0.2.0
  Installed 2 package(s)
</code></pre><p>rack 自动完成<strong>传递依赖解析</strong>：<code>calcx</code> 依赖 <code>mathx</code>，所以 <code>mathx</code> 一起被安装。</p><h2>5. 查看依赖树</h2><pre><code class="language-bash">rack tree
</code></pre><pre><code>demo@0.1.0
└── calcx@0.1.0
    └── mathx@0.2.0
</code></pre><h2>6. 构建并运行</h2><pre><code class="language-bash">rack run
</code></pre><pre><code>built: ./target/bin/demo
10
</code></pre><p>此时项目布局：</p><pre><code>demo/
  rack.toml       # 清单（rack 维护，手改亦可）
  rack.lock       # 锁文件：依赖闭包
  main.rg         # 入口
  target/
    deps/         # 已安装依赖模块 &lt;name&gt;.rg（缓存，可随时重建）
    build/        # 构建暂存区（入口 + 全部依赖，每次构建前清空）
    bin/demo      # 构建产物
</code></pre><h2>7. 锁文件 rack.lock</h2><p><code>install</code> 会把解析后的<strong>完整依赖闭包</strong>写入 <code>rack.lock</code>（rack 维护、随项目入库，勿手改）：</p><pre><code class="language-toml"># rack.lock — 依赖闭包锁文件（rack 维护，勿手改；随项目入库）

[lock.calcx]
version = &quot;0.1.0&quot;
checksum = &quot;130f4c9b…&quot;
dependencies = [&quot;mathx&quot;]

[lock.mathx]
version = &quot;0.2.0&quot;
checksum = &quot;b1dfcea6…&quot;
dependencies = []
</code></pre><ul><li><code>version</code>：解析后的精确版本；</li><li><code>checksum</code>：<code>publish</code> 时记录的模块文件 sha256，<code>install</code> 时先校验再拷贝，<code>build</code> 前也会校验 <code>target/deps</code> 缓存是否被篡改；</li><li><code>dependencies</code>：该包的直接依赖（用于依赖剪枝与完整性校验）。</li></ul><h2>8. 常用命令</h2><table><thead><tr><th>命令</th><th>作用</th></tr></thead><tbody><tr><td><code>rack new &lt;name&gt;</code></td><td>新建项目骨架（rack.toml + main.rg + .gitignore）</td></tr><tr><td><code>rack init [name]</code></td><td>在当前目录初始化 rack 项目</td></tr><tr><td><code>rack install &lt;pkg&gt;[@&lt;ver&gt;]</code></td><td>安装依赖及其全部传递依赖，写入清单与锁文件</td></tr><tr><td><code>rack update</code></td><td>把全部直接依赖重解析到最新版，重写锁文件</td></tr><tr><td><code>rack remove &lt;pkg&gt;</code></td><td>移除依赖，并按依赖边剪掉孤儿传递依赖</td></tr><tr><td><code>rack build</code></td><td>校验锁文件 → 暂存依赖到 target/build → 调用 rgc 编译</td></tr><tr><td><code>rack run [-- &lt;args&gt;...]</code></td><td>构建并运行，参数原样转发给程序</td></tr><tr><td><code>rack tree</code></td><td>打印依赖树</td></tr><tr><td><code>rack list</code></td><td>显示清单与依赖安装状态</td></tr><tr><td><code>rack clean</code></td><td>清除 target/build 与 target/bin（保留 target/deps 缓存）</td></tr><tr><td><code>rack publish</code></td><td>把 <code>&lt;name&gt;.rg</code> 与 rack.toml 发布到本地注册表</td></tr><tr><td><code>rack search [关键字]</code></td><td>在注册表中按包名搜索，显示最新版与描述</td></tr><tr><td><code>rack registry</code></td><td>显示本地注册表路径</td></tr></tbody></table><h3>运行参数透传</h3><p><code>rack run -- &lt;参数&gt;</code> 会把参数原样交给程序，程序用内建 <code>args()</code> 读取（含程序名，行为同 Python 的 <code>sys.argv</code>）：</p><pre><code class="language-bash">rack run -- hello world
</code></pre><pre><code class="language-python">def main() -&gt; int {
    argv = args()
    print(&quot;argc =&quot;, argv.len())
    for a in argv {
        print(&quot;arg:&quot;, a)
    }
    return 0
}
</code></pre><h2>9. 依赖解析：版本冲突与环检测</h2><p>rack 对依赖闭包做完整性保证：</p><ul><li><strong>版本冲突</strong>：同一包被两个依赖 pin 到不同精确版本时，直接报错拒装：</li></ul><pre><code>error: version conflict on `common`: pinned 1.0.0, but `beta` requires 2.0.0
</code></pre><ul><li><strong>依赖环</strong>：<code>A -&gt; B -&gt; A</code> 这样的循环依赖会被检测并拒绝：</li></ul><pre><code>error: dependency cycle: cycleA -&gt; cycleB -&gt; cycleA
</code></pre><p>这两种情况都发生在 <code>install</code> 的解析阶段，不会把半成品写进清单或锁文件。</p><h2>10. 发布自己的包</h2><p>发布一个包只需要两个文件：模块代码 <code>&lt;name&gt;.rg</code> 和清单 <code>rack.toml</code>。</p><p><code>mypkg.rg</code>：</p><pre><code class="language-python">public def add(a: int, b: int) -&gt; int {
    return a + b
}
</code></pre><p><code>rack.toml</code>：</p><pre><code class="language-toml">[package]
name = &quot;mypkg&quot;
version = &quot;0.1.0&quot;
entry = &quot;mypkg.rg&quot;
</code></pre><p>发布并搜索验证：</p><pre><code class="language-bash">cd mypkg
rack publish
rack search mypkg
</code></pre><p>在另一个项目里安装使用：</p><pre><code class="language-bash">rack new usemypkg && cd usemypkg
# 修改 main.rg：import mypkg ...
rack install mypkg
rack run
</code></pre><h2>11. 构建钩子与链接参数</h2><p>有些项目需要在编译前做原生预处理，或链接额外的库。<code>rack.toml</code> 支持 <code>[build]</code> 段：</p><pre><code class="language-toml">[build]
prebuild = &quot;bash tools/llvm-shim.sh&quot;        # 编译前执行（cwd = 项目根目录）
link-args-file = &quot;target/build/link-args&quot;    # 文件内容作为 rgc --link-args
</code></pre><p>RGC 编译器项目本身就是一个 rack 项目（<code>src/rack.toml</code>）：<code>prebuild</code> 负责编译内嵌 LLVM 的后端 shim，<code>link-args-file</code> 把 shim 与 LLVM 静态库的链接参数传给 rgc。</p><h2>12. 下一步</h2><ul><li><a href="https://rgc-lang.github.io/blog/rgc-tutorial-getting-started?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rack-rgc">RGC 入门教程：从 Hello World 到成绩管理器</a></li><li><a href="https://rgc-lang.github.io/blog/pyrig-tutorial-getting-started?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rack-rgc">pyrig 入门：把 RGC 函数变成 Python 原生扩展</a></li><li>语言文档：<a href="https://rgc-lang.github.io/docs/syntax?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rack-rgc">语法基础</a>、<a href="https://rgc-lang.github.io/docs/modules?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rack-rgc">模块系统</a>、<a href="https://rgc-lang.github.io/docs/stdlib?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rack-rgc">标准库</a></li></ul><p>rack 以 Apache 2.0 协议开源。欢迎在 <a href="https://github.com/lexing-2026/vscode-rgc?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rack-rgc">GitHub</a> 提 Issue、贡献代码。</p></div></div><div class='beehiiv__footer'><br class='beehiiv__footer__break'><hr class='beehiiv__footer__line'><a target="_blank" class="beehiiv__footer_link" style="text-align: center;" href="https://www.beehiiv.com/powered-by?publication_logo=https%3A%2F%2Fmedia.beehiiv.com%2Fcdn-cgi%2Fimage%2Ffit%3Dscale-down%2Cformat%3Dauto%2Conerror%3Dredirect%2Cquality%3D80%2Fuploads%2Fpublication%2Flogo%2F9b429155-7f13-4cb8-979a-4eb10bd390af%2Flogo.png%3Fv%3D1792898898&publication_name=RGC+Blogs&utm_campaign=cef5ef92-0f4e-466c-8f42-37e6e64c7a25&utm_medium=post_rss&utm_source=rgc_blogs">Powered by beehiiv</a></div></div>
  ]]></content:encoded>
</item>

      <item>
  <title>pyrig 入门:把 RGC 函数变成 Python 原生扩展</title>
  <description>pyrig 是 RGC 的官方 Python 绑定框架。这篇教程从安装开始,带你用标准工作流把 RGC 函数导出为 CPython 扩展模块,并用 Fibonacci 实测性能提升。</description>
  <link>https://rgc-dev.beehiiv.com/p/new-post</link>
  <guid isPermaLink="true">https://rgc-dev.beehiiv.com/p/new-post</guid>
  <pubDate>Sat, 24 Oct 2026 17:34:41 +0000</pubDate>
  <atom:published>2026-10-24T17:34:41Z</atom:published>
    <category><![CDATA[Python]]></category>
    <category><![CDATA[Tutorial]]></category>
  <content:encoded><![CDATA[
    <div class='beehiiv'><style>
  .bh__table, .bh__table_header, .bh__table_cell { border: 1px solid #C0C0C0; }
  .bh__table_cell { padding: 5px; background-color: #FFFFFF; }
  .bh__table_cell p { color: #2D2D2D; font-family: 'Helvetica',Arial,sans-serif !important; overflow-wrap: break-word; }
  .bh__table_header { padding: 5px; background-color:#F1F1F1; }
  .bh__table_header p { color: #2A2A2A; font-family:'Trebuchet MS','Lucida Grande',Tahoma,sans-serif !important; overflow-wrap: break-word; }
</style><div class='beehiiv__body'><div class="custom_html"><p>Python 生态强大，但解释器执行热循环确实慢。常见的解法是把热点用 C/C++ 或 Rust 重写。</p><p>RGC 也提供了原生扩展能力：<strong>pyrig</strong>——RGC 官方 Python 绑定框架。把 RGC 函数导出为 <strong>CPython 扩展模块</strong>，Python 侧直接 <code>import</code>，性能却是原生机器码。</p><p>这篇教程从安装开始，走一遍完整流程：脚手架 → 构建 → <code>import</code> 调用 → 类型映射 → 实战性能对比，最后说明当前限制。所有命令都在本仓库验证过，可以直接复制运行。</p><h2>1. pyrig 是什么</h2><p>pyrig 把 RGC 函数变成 Python 可以直接导入的扩展模块，实现直接走 <strong>CPython C API</strong>：</p><ul><li>为每个导出函数生成 C 胶水：<code>PyArg_ParseTuple</code> 参数解析、RGC ↔ Python 类型转换、<code>PyMethodDef</code> 方法表、<code>PyInit_&lt;module&gt;</code> 模块入口；</li><li>用 <code>rgc --emit-object</code> 把 RGC 源码编译成 PIC 目标文件；</li><li>链接为 <code>.so</code> 共享库（<strong>不依赖 libpython</strong>，符号由解释器在 <code>import</code> 时解析，与官方扩展构建方式一致）。</li></ul><h2>2. 安装与准备</h2><p>先构建编译器（参见 <a href="https://rgc-lang.github.io/blog/rgc-tutorial-getting-started?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=pyrig-rgc-python">RGC 入门教程</a>）：</p><pre><code class="language-bash">cd RGLite
cd src
./build.sh        # 产物：src/build/rgc3
cd ..
</code></pre><p>项目根目录的 <code>build/rgc</code> 可以直接使用。然后安装 pyrig：</p><pre><code class="language-bash">pip install -e pyrig/
</code></pre><p>或者不安装，直接用模块入口：</p><pre><code class="language-bash">PYTHONPATH=pyrig python3 -m pyrig --version
# pyrig 0.2.0
</code></pre><h2>3. 快速开始</h2><h3>3.1 生成项目骨架</h3><pre><code class="language-bash">python3 -m pyrig new string_sum     # 若已 pip install：pyrig new string_sum
cd string_sum
</code></pre><p>生成三个文件：</p><pre><code>string_sum/
├── README.md
├── pyproject.toml
└── string_sum.rg
</code></pre><h3>3.2 RGC 侧代码</h3><p>打开 <code>string_sum.rg</code>：</p><pre><code class="language-python">import pyrig

# Computes the sum of two integers.
public def add(a: int, b: int) -&gt; int {
    return a + b
}

# Greets someone by name.
public def greet(name: str) -&gt; str {
    return &quot;hello, &quot; + name + &quot;!&quot;
}

# 标记要导出的函数：pyrig.export(&quot;python 侧名字&quot;)
pyrig.export(&quot;add&quot;)
pyrig.export(&quot;greet&quot;)
</code></pre><p>核心就三件事：</p><ul><li><code>import pyrig</code> 引入绑定运行时模块；</li><li>想导出的函数必须是 <strong><code>public</code></strong>，并且带<strong>显式类型注解</strong>（胶水需要 C 签名）；</li><li><code>pyrig.export(&quot;add&quot;)</code> 是<strong>编译期标记</strong>，告诉构建器生成胶水；运行时是空操作，不会出现在生成的机器码里。</li></ul><p>函数上方的 <code>#</code> 注释会变成 Python 侧的 <code>__doc__</code>，在 Python 里用 <code>help()</code> 或 <code>.__doc__</code> 就能看到。</p><h3>3.3 构建</h3><pre><code class="language-bash">python3 -m pyrig build
# built: dist/string_sum.cpython-313-x86_64-linux-gnu.so
</code></pre><p>构建器自动向上发现 <code>pyproject.toml</code> 里的 <code>[tool.pyrig]</code> 段，产物在 <code>dist/</code> 下：</p><pre><code>dist/
├── string_sum.cpython-313-x86_64-linux-gnu.so
└── pyrig_shim_string_sum.c   # 生成的 C 胶水（可阅读）
</code></pre><h3>3.4 导入使用</h3><pre><code class="language-bash">PYTHONPATH=dist python3 -c &quot;import string_sum; print(string_sum.add(3, 4))&quot;
# 7
</code></pre><p>Python 侧零配置，就是一个普通的扩展模块：</p><pre><code class="language-python">import string_sum

print(string_sum.add(3, 4))            # 7
print(string_sum.greet(&quot;rgc&quot;))            # hello, rgc!
print(string_sum.add.__doc__)
# Computes the sum of two integers.
</code></pre><h2>4. 直接构建已有的 .rg 文件</h2><p>不想建项目时，可以直接用 <code>pyrig build &lt;文件&gt;</code> 指定模块名和输出目录。仓库的 <code>examples/pyrig_demo.rg</code> 是一个完整的示例：</p><pre><code class="language-python">import pyrig

public def add(a: int, b: int) -&gt; int {
    return a + b
}

public def greet(name: str) -&gt; str {
    return &quot;hello, &quot; + name + &quot;!&quot;
}

public def is_even(n: int) -&gt; bool {
    return n % 2 == 0
}

public def dist(ax: float, ay: float, bx: float, by: float) -&gt; float {
    dx = ax - bx
    dy = ay - by
    return sqrt(dx * dx + dy * dy)
}

public def say_hi() -&gt; None {
    puts(&quot;hi from RGC&quot;)
}

pyrig.export(&quot;add&quot;)
pyrig.export(&quot;greet&quot;)
pyrig.export(&quot;is_even&quot;)
pyrig.export(&quot;dist&quot;)
pyrig.export(&quot;say_hi&quot;)

# extern def 与 pyrig 可混用：puts 来自 libc
extern def puts(s: str) -&gt; int
</code></pre><p>构建并验证：</p><pre><code class="language-bash">python3 -m pyrig build examples/pyrig_demo.rg -n pyrig_demo -o build/pyrig
PYTHONPATH=build/pyrig python3 -c &quot;import pyrig_demo; print(pyrig_demo.add(3, 4))&quot;
</code></pre><p>输出：</p><pre><code>7
</code></pre><p>这个示例同时展示了两个点：</p><ul><li><code>dist</code> 用了标准库的 <code>sqrt</code>，返回 <code>float</code>；</li><li><code>say_hi</code> 通过 <code>extern def puts</code> 直接调 libc，说明 <strong>extern def（FFI）和 pyrig 可以混用</strong>。</li></ul><h2>5. 类型映射（RGC ↔ Python）</h2><p>pyrig 当前支持五种标量类型的双向转换：</p><table><thead><tr><th>RGC</th><th>Python</th><th>参数解析</th><th>返回值构造</th></tr></thead><tbody><tr><td><code>int</code></td><td><code>int</code></td><td><code>&quot;L&quot;</code> (long long)</td><td><code>PyLong_FromLongLong</code></td></tr><tr><td><code>float</code></td><td><code>float</code></td><td><code>&quot;d&quot;</code></td><td><code>PyFloat_FromDouble</code></td></tr><tr><td><code>bool</code></td><td><code>bool</code></td><td><code>&quot;p&quot;</code></td><td><code>PyBool_FromLong</code></td></tr><tr><td><code>str</code></td><td><code>str</code></td><td><code>&quot;s&quot;</code> (UTF-8)</td><td><code>PyUnicode_FromString</code></td></tr><tr><td><code>None</code></td><td><code>None</code></td><td>—</td><td><code>Py_RETURN_NONE</code></td></tr></tbody></table><p>参数个数或类型不匹配时，CPython 会抛出标准 <code>TypeError</code>，和调用普通 C 扩展的体验一致。</p><h2>6. 导出规则与项目配置</h2><h3>6.1 导出规则</h3><ul><li>导出函数必须写在<strong>入口文件</strong>，且带显式类型注解。</li><li>支持的类型：<code>int</code> / <code>float</code> / <code>bool</code> / <code>str</code> / <code>None</code>。</li><li><code>pyrig.export(&quot;python 名&quot;)</code> 默认用 RGC 函数名；改名导出用 <code>pyrig.export(&quot;py 名&quot;, &quot;rgc 函数名&quot;)</code>（两函数需 ABI 兼容）。</li></ul><h3>6.2 pyproject.toml</h3><p>在项目内 <code>pyrig build</code> 会自动向上发现 <code>[tool.pyrig]</code> 段：</p><pre><code class="language-toml">[tool.pyrig]
name = &quot;string_sum&quot;     # 扩展模块名（默认项目目录名）
source = &quot;string_sum.rg&quot;
out-dir = &quot;dist&quot;
# rgc = &quot;build/rgc&quot;     # 编译器路径（默认 RGC env / PATH / 仓库 build/rgc）
# cc = &quot;cc&quot;
# release = true        # false -&gt; rgc -O0
# link-args = &quot;&quot;
</code></pre><p><code>build</code> 命令的常用选项：</p><table><thead><tr><th>选项</th><th>作用</th></tr></thead><tbody><tr><td><code>-n, --name</code></td><td>扩展模块名（默认：源文件名 / pyproject 项目名）</td></tr><tr><td><code>-o, --out</code></td><td>输出目录</td></tr><tr><td><code>--rgc</code></td><td>rgc 编译器路径（默认 <code>RGC</code> 环境变量 / <code>PATH</code> / 仓库 <code>build/rgc</code>）</td></tr><tr><td><code>--cc</code></td><td>C 编译器（默认 <code>cc</code>）</td></tr><tr><td><code>--debug</code></td><td>不优化构建（<code>rgc -O0</code>）</td></tr></tbody></table><p><code>pyrig develop</code> 会把构建好的扩展安装到当前激活的 virtualenv，开发时直接 <code>import</code> 即可。</p><h2>7. 实战：Fibonacci 性能对比</h2><p>下面用 pyrig 导出一个递归 <code>fib</code>，看看&quot;用 RGC 写热点&quot;到底能快多少。</p><p>新建项目并把 <code>fib_demo.rg</code> 改成：</p><pre><code class="language-python">import pyrig

# Computes the n-th Fibonacci number (recursive).
public def fib(n: int) -&gt; int {
    if n &lt;= 1 {
        return n
    }
    return fib(n - 1) + fib(n - 2)
}

pyrig.export(&quot;fib&quot;)
</code></pre><p>构建并测试：</p><pre><code class="language-bash">python3 -m pyrig build
PYTHONPATH=dist python3 - &lt;&lt;&#39;EOF&#39;
import fib_demo, time

print(&quot;fib(10) =&quot;, fib_demo.fib(10))
print(&quot;fib(20) =&quot;, fib_demo.fib(20))

t0 = time.perf_counter()
print(&quot;fib(30) =&quot;, fib_demo.fib(30))
t1 = time.perf_counter()
print(f&quot;RGC 用时: {(t1 - t0) * 1000:.1f} ms&quot;)

def pyfib(n):
    return n if n &lt;= 1 else pyfib(n - 1) + pyfib(n - 2)

t0 = time.perf_counter()
pyfib(30)
t1 = time.perf_counter()
print(f&quot;Python 用时: {(t1 - t0) * 1000:.1f} ms&quot;)
EOF
</code></pre><p>本机实测（Python 3.13 / RGC v0.2）：</p><pre><code>fib(10) = 55
fib(20) = 6765
fib(30) = 832040
RGC 用时: 1.7 ms
Python 用时: 50.4 ms
</code></pre><p>同一个递归算法，RGC 快约 <strong>30 倍</strong>。这就是&quot;语法像 Python、性能像 C&quot;的直观体现——你不需要改算法，只需要把热点函数用 RGC 重写一遍，然后从 Python 正常调用。</p><h2>8. 当前限制（v0.2）</h2><p>pyrig 还很年轻，以下限制在后续版本会逐步放开：</p><ul><li>只支持<strong>入口文件的标量函数</strong>；方法、类、容器（List/Map）导出待实现。</li><li><code>str</code> 参数指针只在调用期间有效，不要把传入的 <code>str</code> 长期持有；<code>str</code> 返回值暂不回收（RGC 无 GC）。</li><li>不支持关键字参数、默认值参数。</li><li>无 <code>PyErr</code> 异常传播——RGC 错误建议返回 <code>Result</code> 并在 RGC 层处理。</li></ul><h2>9. 下一步</h2><ul><li>完整文档：仓库 <code>docs/compiler/FFI.md</code>（<code>extern def</code> 调用 C 库 + pyrig 详解）</li><li>语言基础：<a href="https://rgc-lang.github.io/blog/rgc-tutorial-getting-started?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=pyrig-rgc-python">RGC 入门教程</a></li><li>回归测试：<code>tests/run_pyrig.sh</code>（构建 + CPython 实际 import 断言）；<code>pyrig/tests/</code> 有 pytest 单元测试</li></ul><p>pyrig 以 Apache 2.0 协议开源。欢迎在 <a href="https://github.com/lexing-2026/vscode-rgc?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=pyrig-rgc-python">GitHub</a> 提 Issue、贡献代码。如果你有现成的 Python 热点函数，不妨试试用 RGC 重写——也许就是几倍的性能提升。</p></div></div><div class='beehiiv__footer'><br class='beehiiv__footer__break'><hr class='beehiiv__footer__line'><a target="_blank" class="beehiiv__footer_link" style="text-align: center;" href="https://www.beehiiv.com/powered-by?publication_logo=https%3A%2F%2Fmedia.beehiiv.com%2Fcdn-cgi%2Fimage%2Ffit%3Dscale-down%2Cformat%3Dauto%2Conerror%3Dredirect%2Cquality%3D80%2Fuploads%2Fpublication%2Flogo%2F9b429155-7f13-4cb8-979a-4eb10bd390af%2Flogo.png%3Fv%3D1792898898&publication_name=RGC+Blogs&utm_campaign=8538aabd-a45d-4f79-9614-11fc8e84f078&utm_medium=post_rss&utm_source=rgc_blogs">Powered by beehiiv</a></div></div>
  ]]></content:encoded>
</item>

      <item>
  <title>RGC 入门教程:从 Hello World 到成绩管理器</title>
  <description>一篇写给 Python 开发者的 RGC 入门教程——环境搭建、基础语法、类型系统、所有权与借用、泛型与接口、模块与标准库,最后用一个成绩管理器小项目串联全部知识。</description>
  <link>https://rgc-dev.beehiiv.com/p/new-post-d64e</link>
  <guid isPermaLink="true">https://rgc-dev.beehiiv.com/p/new-post-d64e</guid>
  <pubDate>Sat, 24 Oct 2026 16:36:13 +0000</pubDate>
  <atom:published>2026-10-24T16:36:13Z</atom:published>
    <category><![CDATA[Tutorial]]></category>
  <content:encoded><![CDATA[
    <div class='beehiiv'><style>
  .bh__table, .bh__table_header, .bh__table_cell { border: 1px solid #C0C0C0; }
  .bh__table_cell { padding: 5px; background-color: #FFFFFF; }
  .bh__table_cell p { color: #2D2D2D; font-family: 'Helvetica',Arial,sans-serif !important; overflow-wrap: break-word; }
  .bh__table_header { padding: 5px; background-color:#F1F1F1; }
  .bh__table_header p { color: #2A2A2A; font-family:'Trebuchet MS','Lucida Grande',Tahoma,sans-serif !important; overflow-wrap: break-word; }
</style><div class='beehiiv__body'><div class="custom_html"><p>RGC 是一门 <strong>Python 风格、编译型、内存安全</strong> 的系统编程语言。语法上你几乎不用重新学习——<code>def</code>、<code>if</code>、<code>for</code>、<code>and</code>、<code>None</code> 都还在；但它在编译期完成类型检查和所有权检查，由 LLVM 生成原生机器码，性能接近 C / Rust。</p><p>这篇教程面向 Python 开发者，从零开始：先跑起第一个程序，再逐个掌握语法、类型、所有权、泛型、模块与标准库，最后用一个<strong>成绩管理器</strong>小项目把全部知识串起来。所有示例都来自仓库中可编译运行的代码，你可以直接复制运行。</p><h2>1. 环境准备</h2><h3>1.1 构建编译器</h3><p>RGC 采用自举（bootstrapping）构建：<code>stage0</code> 是 C++ 编写的一次性种子，之后由 RGC 自身逐级编译出 <code>stage1</code> → <code>stage2</code> → <code>stage3</code>，最终编译器完全由 RGC 构建。</p><p>先安装依赖：</p><ul><li><strong>LLVM 23</strong>（自包含发行包，默认路径 <code>/home/bluemoon/llvm/LLVM-23.1.4-Linux-X64/bin</code>）</li><li><strong>CMake</strong> ≥ 3.31</li><li><strong>GCC</strong> 13.3+ 或 Clang</li></ul><p>克隆仓库并构建：</p><pre><code class="language-bash">git clone https://github.com/lexing-2026/vscode-rgc
cd RGLite
cd src
./build.sh
</code></pre><p>首次构建会自动编译 C++ 引导种子；之后 <code>rack</code> 会管理 <code>rgc1</code> → <code>rgc2</code> → <code>rgc3</code> 的逐级自举，并校验 IR 不动点。构建产物在 <code>src/build/rgc3</code>。</p><h3>1.2 编译并运行第一个程序</h3><pre><code class="language-bash">cd src
./build/rgc3 ../examples/hello.rg -o /tmp/hello
/tmp/hello
</code></pre><p>输出：</p><pre><code>hello from RGC, x + y = 42
condition: ok
score 95 =&gt; excellent
score 70 =&gt; pass
score 30 =&gt; fail
flag = True
7 // 2 = 3  7 % 2 = 1  2 ** 10 = 1024
</code></pre><p><code>rgc3</code> 内嵌 LLVM，运行时只需要系统链接器 <code>gcc</code>，不需要额外安装 <code>llc</code> 或 <code>clang</code>。</p><h2>2. 第一个程序：Hello World</h2><p>来看 <code>examples/hello.rg</code> 的完整内容：</p><pre><code class="language-python">def add(a: int, b: int) -&gt; int {
    return a + b
}

def classify(score: int) -&gt; str {
    if score &gt;= 90 {
        return "excellent"
    } elif score &gt;= 60 {
        return "pass"
    } else {
        return "fail"
    }
}

def main() {
    x = 40
    y: int = 2
    total = add(x, y)
    print("hello from RGC, x + y =", total)

    if x &gt; 10 and y &lt; 10 {
        print("condition: ok")
    } else {
        print("condition: no")
    }

    flag = not (x == 0)
    print("flag =", flag)
    print("7 // 2 =", 7 // 2, " 7 % 2 =", 7 % 2, " 2 ** 10 =", 2 ** 10)
}
</code></pre><p>即使没有 Python 背景，这段代码也几乎可以无障碍阅读。几个要点：</p><ul><li><strong>入口函数</strong>是 <code>main()</code>，和 Python 脚本一样。</li><li>变量 <code>x = 40</code><strong>无需 <code>mut</code></strong>——RGC 的变量默认可变，符合 Python 习惯。</li><li><code>y: int = 2</code> 是<strong>显式类型注解</strong>；<code>x</code> 则由编译器<strong>推断</strong>为 <code>int</code>。</li><li>块结构用大括号 <code>{}</code>，<strong>不依赖缩进</strong>，注释是 <code>#</code>。</li><li>逻辑运算符沿用 Python 风格：<code>and</code>、<code>or</code>、<code>not</code>。</li><li><code>//</code>（整除）、<code>%</code>（取模）、<code>**</code>（幂）都与 Python 一致。</li></ul><p>注意一个与 Python 不同的细节：<strong>两个整数相除 <code>/</code> 得到整数</strong>（与 C 一致），浮点数参与才会得到浮点结果。例如 <code>7 / 2</code> 结果是 <code>3</code>，而 <code>7.0 / 2</code> 是 <code>3.5</code>。</p><h2>3. 变量与类型系统</h2><p>RGC 是<strong>静态类型</strong>语言：每个表达式在编译期都有确定的类型。但类型推断让你不必到处写注解。</p><table><thead><tr><th>类型</th><th>说明</th><th>示例</th></tr></thead><tbody><tr><td><code>int</code></td><td>整数</td><td><code>42</code></td></tr><tr><td><code>float</code></td><td>浮点数</td><td><code>3.14</code></td></tr><tr><td><code>bool</code></td><td>布尔值</td><td><code>True</code> / <code>False</code></td></tr><tr><td><code>str</code></td><td>字符串</td><td><code>"hello"</code></td></tr><tr><td><code>None</code></td><td>空值</td><td><code>None</code></td></tr></tbody></table><pre><code class="language-python">def main() {
    count = 1          # 推断为 int
    name = "RGC"       # 推断为 str
    ratio: float = 0.5 # 显式注解为 float
    ok: bool = True
}
</code></pre><p>函数签名可以完整标注参数与返回类型，让错误尽早暴露在编译期：</p><pre><code class="language-python">def scale(x: float, factor: int) -&gt; float {
    return x * factor
}
</code></pre><h2>4. 函数与控制流</h2><h3>4.1 函数</h3><pre><code class="language-python">def greet(name: str) {
    print("Hello,", name)
}
</code></pre><p>返回值类型可以省略；需要返回时用 <code>return</code>。</p><h3>4.2 if / elif / else</h3><pre><code class="language-python">def classify(n: int) -&gt; str {
    if n &lt; 0 {
        return "negative"
    } elif n == 0 {
        return "zero"
    } else {
        return "positive"
    }
}
</code></pre><h3>4.3 循环：for / while / break / continue / pass</h3><pre><code class="language-python">def main() {
    # for 遍历 range
    for i in range(5) {        # 0 1 2 3 4
        print(i)
    }

    # while + continue + break
    i = 0
    while i &lt; 6 {
        i = i + 1
        if i == 2 {
            continue
        }
        if i == 5 {
            break
        }
        print("i =", i)
    }

    # pass 空语句
    n = 0
    while n &lt; 3 {
        n = n + 1
        pass
    }
}
</code></pre><p><code>range</code>、<code>break</code>、<code>continue</code>、<code>pass</code> 的语义与 Python 一致，只是块结构换成大括号。</p><h2>5. 类、枚举与模式匹配</h2><p>RGC 提供完整的代数数据类型（ADT）：<code>class</code> 组织数据与方法，<code>enum</code> 描述"要么是 A、要么是 B"的枚举，配合 <code>match</code> 做穷尽的模式匹配。</p><pre><code class="language-python">class Point {
    x: int
    y: int
    def sum(self) -&gt; int {
        return self.x + self.y
    }
}

enum Shape {
    Circle(float)
    Rect { w: float, h: float }
}

def area(s: Shape) -&gt; float {
    match s {
        case Circle(r) =&gt; 3.14159 * r * r
        case Rect { w, h } =&gt; w * h
        case _ =&gt; 0.0
    }
}

def main() {
    p = Point()
    p.x = 3
    p.y = 4
    print("p.sum() =", p.sum())   # 7

    c = Circle(2.0)
    r = Rect(3.0, 4.0)
    print("area(circle) =", area(c))
    print("area(rect)  =", area(r))
}
</code></pre><p>几个和 Python 不一样的写法：</p><ul><li>枚举变体用<strong>构造函数语法</strong>创建：<code>Circle(2.0)</code>、<code>Rect(3.0, 4.0)</code>；没有参数的单位变体写成 <code>Pass()</code>。</li><li><code>match</code> 的 <code>case</code> 不需要括号：<code>case Circle(r)</code> 直接把负载绑定到变量 <code>r</code>。</li><li><code>case _</code> 是通配分支，保证匹配一定完整。</li></ul><h2>6. 所有权与借用</h2><p>这是 RGC 内存安全的核心，也是和 Python 最大的不同。<strong>每个值有唯一的拥有者</strong>，离开作用域即被释放；通过<strong>借用</strong>安全地共享访问。全程没有 GC，零运行时开销。</p><h3>6.1 移动（move）</h3><p>自定义类型（<code>class</code> / <code>enum</code>）默认是 <strong>move 语义</strong>。赋值后原变量不再可用：</p><pre><code class="language-python">class Point {
    x: int
    def sum(self) -&gt; int {
        return self.x
    }
}

def main() {
    a = Point()
    a.x = 5
    b = a              # 所有权从 a 移动到 b
    print("b.x =", b.x)   # 5
    # print(a)         # 编译错误：a 已被 move
}
</code></pre><p>被移动的变量在<strong>重新赋值</strong>后可以恢复可用：</p><pre><code class="language-python">d = Point()
d.x = 7
e = d                # move d -&gt; e
d = Point()          # 重新赋值，d 恢复可用
d.x = 8
</code></pre><h3>6.2 只读借用 <code>@</code> 与可变借用 <code>@var</code></h3><p>不想转移所有权、只想读，用 <code>@</code> 借用。以自定义类型为例：</p><pre><code class="language-python">class Counter {
    value: int
}

def read(c: @Counter) -&gt; int {
    return c.value
}

def main() {
    x = Counter()
    x.value = 10

    r1 = @x       # 只读借用
    r2 = @x       # 多个 @ 可以并存
    print("read(r1) =", read(r1))   # 10
    print("read(r2) =", read(r2))   # 10
    print("x.value =", x.value)     # x 仍然可用
}
</code></pre><p>想修改，用 <code>@var</code> 可变借用（独占访问）：</p><pre><code class="language-python">def push_zero(lst: @var List[int]) {
    lst.push(0)
}
</code></pre><p>多个 <code>@</code> 只读借用可以并存；<code>@var</code> 与任何其他借用互斥——这一切都在<strong>编译期</strong>检查，保证没有 use-after-move、悬垂引用和数据竞争。</p><h3>6.3 方法调用自动借用</h3><p>调用 <code>self</code> 方法时，方法按借用语义自动处理，不需要手动写 <code>@</code>。可变方法自动使用可变借用：</p><pre><code class="language-python">class Counter {
    value: int
    def inc(self) {
        self.value = self.value + 1
    }
}

def main() {
    z = Counter()
    z.value = 30
    z.inc()           # self 自动可变借用
    print(z.value)    # 31，z 仍可用
}
</code></pre><h2>7. 泛型与接口</h2><h3>7.1 泛型函数</h3><pre><code class="language-python">def identity[T](x: T) -&gt; T {
    return x
}

def pair_sum[T](a: T, b: T) -&gt; T {
    return a + b
}

def main() {
    print(identity(42))        # 42
    print(identity(3.14))      # 3.14
    print(pair_sum(2, 3))      # 5
    print(pair_sum(1.5, 2.5))  # 4.0
}
</code></pre><h3>7.2 泛型类</h3><pre><code class="language-python">class Box[T] {
    value: T
    def get(self) -&gt; T {
        return self.value
    }
}

def main() {
    b = Box[int]()
    b.value = 42
    print(b.get())        # 42

    f = Box[float]()
    f.value = 3.14
    print(f.get())        # 3.14
}
</code></pre><h3>7.3 接口与边界约束</h3><p>接口定义行为契约，类通过 <code>class T : Interface</code> 实现：</p><pre><code class="language-python">interface Show {
    def show(self) -&gt; str
}

class Point : Show {
    x: int
    y: int
    def show(self) -&gt; str {
        return "Point"
    }
}

class Line : Show {
    a: int
    b: int
    def show(self) -&gt; str {
        return "Line"
    }
}

# T 受 Show 约束，函数体内可直接调用接口方法
def describe[T: Show](x: T) -&gt; str {
    return x.show()
}

def main() {
    p = Point()
    p.x = 1
    p.y = 2
    print(describe(p))   # Point

    l = Line()
    l.a = 3
    l.b = 4
    print(describe(l))   # Line
}
</code></pre><p>泛型通过<strong>单态化</strong>编译：每个具体类型生成专用代码，没有虚表、没有装箱，性能和手写专用实现一致。</p><h2>8. 模块系统</h2><p>用 <code>import</code> 引入模块，模块内部通过 <code>public</code> 控制可见性。未加 <code>public</code> 的项只在模块内部可见。</p><p><code>geometry.rg</code>：</p><pre><code class="language-python">public class Point {
    x: int
    y: int
    def sum(self) -&gt; int {
        return self.x + self.y
    }
}

# 私有函数：仅模块内部可见
def double(v: int) -&gt; int {
    return v * 2
}

public def make_point(x: int, y: int) -&gt; Point {
    p = Point()
    p.x = x
    p.y = y
    return p
}

public def norm_sq(p: Point) -&gt; int {
    return double(p.x * p.x + p.y * p.y)
}
</code></pre><p><code>main.rg</code>：</p><pre><code class="language-python">import geometry

def main() {
    p = make_point(3, 4)
    print("point sum =", p.sum())   # 7
    print("norm_sq   =", norm_sq(p))  # 50
}
</code></pre><p>注意 <code>norm_sq</code> 内部调用了私有函数 <code>double</code>，但对外只暴露 <code>public</code> 项——内部实现细节被安全地封装在模块边界内。</p><h2>9. 标准库初探</h2><p>标准库目前提供内建核心类型与方法：<code>to_string</code>、字符串方法、<code>List[T]</code>、<code>Maybe[T]</code>、<code>Result[T, E]</code>。</p><h3>9.1 字符串</h3><pre><code class="language-python">def main() {
    msg = "Hello, " + "RGC"
    print(msg.len())                  # 10
    print(msg.contains("lo,"))        # True
    print(msg.startswith("Hello"))    # True
    print(msg.endswith("RGC"))        # True

    print("hello world".slice(0, 5))  # hello
    print("12345".to_int().unwrap())  # 12345
}
</code></pre><h3>9.2 List</h3><pre><code class="language-python">def main() {
    xs = List[int]()
    xs.push(1)
    xs.push(2)
    xs.push(3)
    print(xs.len())          # 3
    print(xs.get(0))         # 1
    xs.set(1, 20)
    print(xs.get(1))         # 20
    print(xs.contains(3))    # True
    print(xs.pop())          # 3

    total = 0
    for x in xs {
        total = total + x
    }
    print(total)             # 21
}
</code></pre><h3>9.3 Maybe 与 Result</h3><p>RGC 用 <code>Result[T, Err]</code> 表达可恢复错误：不抛异常、不静默失败。解析字符串可能失败时，签名里就写着"可能失败"：</p><pre><code class="language-python">def main() {
    ok = Result[int, str].Ok(7)
    err = Result[int, str].Err("boom")
    print(ok.is_ok())    # True
    print(err.is_err())  # True

    # match 推荐用法：错误分支显式处理
    match err {
        case Ok(v) =&gt; print("unexpected:", v)
        case Err(msg) =&gt; print("error is:", msg)
    }
}
</code></pre><p>配合字符串的 <code>to_int()</code>：</p><pre><code class="language-python">r = "12345".to_int()
match r {
    case Ok(v) =&gt; print("value =", v)     # value = 12345
    case Err(msg) =&gt; print("err:", msg)
}

bad = "abc".to_int()
match bad {
    case Ok(v) =&gt; print("unexpected:", v)
    case Err(msg) =&gt; print("to_int error:", msg)   # invalid integer literal
}
</code></pre><h2>10. 实战：成绩管理器</h2><p>现在把上面的知识串起来，写一个小程序：录入三名学生成绩，输出每个人的等级、及格人数和平均分。这会用到<strong>类、接口、枚举、模式匹配、List、所有权与借用、泛型边界</strong>。</p><pre><code class="language-python">interface Show {
    def show(self) -&gt; str
}

class Student : Show {
    name: str
    score: int
    def show(self) -&gt; str {
        return self.name + ": " + to_string(self.score)
    }
    def is_pass(self) -&gt; bool {
        return self.score &gt;= 60
    }
}

enum Grade {
    Excellent
    Pass
    Fail
}

def grade_of(score: int) -&gt; Grade {
    if score &gt;= 90 {
        return Excellent()
    } elif score &gt;= 60 {
        return Pass()
    } else {
        return Fail()
    }
}

def grade_name(g: Grade) -&gt; str {
    match g {
        case Excellent =&gt; "优秀"
        case Pass =&gt; "及格"
        case Fail =&gt; "不及格"
        case _ =&gt; "?"
    }
}

def total(students: @List[Student]) -&gt; int {
    sum = 0
    for s in students {
        sum = sum + s.score
    }
    return sum
}

def count_pass(students: @List[Student]) -&gt; int {
    n = 0
    for s in students {
        if s.is_pass() {
            n = n + 1
        }
    }
    return n
}

def main() {
    students = List[Student]()

    s = Student()
    s.name = "Alice"
    s.score = 92
    students.push(s)          # push 移动所有权，s 可重新赋值

    s = Student()
    s.name = "Bob"
    s.score = 74
    students.push(s)

    s = Student()
    s.name = "Carol"
    s.score = 55
    students.push(s)

    for st in students {
        print(st.show(), "=&gt;", grade_name(grade_of(st.score)))
    }

    print("及格人数 =", count_pass(@students))
    print("平均分 =", total(@students) / students.len())
}
</code></pre><p>运行输出：</p><pre><code>Alice: 92 =&gt; 优秀
Bob: 74 =&gt; 及格
Carol: 55 =&gt; 不及格
及格人数 = 2
平均分 = 73
</code></pre><p>几个值得回味的点：</p><ul><li><code>students.push(s)</code> 把 <code>s</code><strong>移动</strong>进列表；之后给 <code>s</code> 重新赋值一个新 <code>Student()</code>，符合所有权模型。</li><li><code>for st in students</code> 按借用迭代，循环结束后 <code>students</code> 仍然可用。</li><li><code>count_pass(@students)</code> 和 <code>total(@students)</code> 用 <code>@</code><strong>只读借用</strong>传入列表，调用后 <code>students</code> 不受影响。</li><li><code>grade_name</code> 用 <code>match</code> 把枚举变体映射成中文标签，编译期保证分支完整。</li><li><code>class Student : Show</code> 实现了接口，<code>show()</code> 在 <code>for</code> 循环里被多态调用（单态化，无虚表开销）。</li></ul><h2>11. 下一步</h2><p>至此你已经掌握了 RGC 的核心：从语法、类型，到所有权、泛型、模块和标准库。继续深入：</p><ul><li><a href="https://rgc-lang.github.io/docs/syntax?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-hello-world">语法基础</a></li><li><a href="https://rgc-lang.github.io/docs/types?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-hello-world">类型系统</a></li><li><a href="https://rgc-lang.github.io/docs/ownership?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-hello-world">所有权与借用</a></li><li><a href="https://rgc-lang.github.io/docs/generics?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-hello-world">泛型与接口</a></li><li><a href="https://rgc-lang.github.io/docs/modules?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-hello-world">模块系统</a></li><li><a href="https://rgc-lang.github.io/docs/stdlib?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-hello-world">标准库</a></li></ul><p>RGC 以 Apache 2.0 协议开源。欢迎在 <a href="https://github.com/lexing-2026/vscode-rgc?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-hello-world">GitHub</a> 提 Issue、贡献代码；也欢迎安装 <a href="https://github.com/lexing-2026/vscode-rgc?utm_source=rgc-dev.beehiiv.com&utm_medium=newsletter&utm_campaign=rgc-hello-world">VSCode 插件</a>，获得语法高亮与补全支持。祝你写得开心！</p></div></div><div class='beehiiv__footer'><br class='beehiiv__footer__break'><hr class='beehiiv__footer__line'><a target="_blank" class="beehiiv__footer_link" style="text-align: center;" href="https://www.beehiiv.com/powered-by?publication_logo=https%3A%2F%2Fmedia.beehiiv.com%2Fcdn-cgi%2Fimage%2Ffit%3Dscale-down%2Cformat%3Dauto%2Conerror%3Dredirect%2Cquality%3D80%2Fuploads%2Fpublication%2Flogo%2F9b429155-7f13-4cb8-979a-4eb10bd390af%2Flogo.png%3Fv%3D1792898898&publication_name=RGC+Blogs&utm_campaign=e93c9684-c352-4915-b3a8-4d562936a334&utm_medium=post_rss&utm_source=rgc_blogs">Powered by beehiiv</a></div></div>
  ]]></content:encoded>
</item>

  </channel>
</rss>
