渲染zh-Hans

通道

Translation status: 简体中文 reader-locale proof. Term names and code fences follow the zh-Hans pack; supporting prose may still be English.

A 通道 closes itself when its conversation completes; a pool of many keeps only the unfinished ones open, and close() ends one early and reports its error.

Syntax: 常量 布尔 clausa ← s.close()

Category#

endpoint

Examples#

radix/corpus/ad/sermo-channel.fab (canonical · type)#

English reader names for the conversation family: channel, frame, send<T>, recv<T>

# =============================================================================
# channel — the conversation family under the English reader surface.
# =============================================================================
#
# What this teaches:
#   • `channel` is the en spelling of `通道`, the handle `call` returns
#   • `frame<T>` is the en spelling of `帧<T>`, one typed frame
#   • `s.send<T>()` / `s.recv<T>()` are the en spellings of the outbound
#     `发送<T>` and inbound `接收<T>` views
#
# Common mistakes:
#   • treating the words as reserved: `channel`, `frame`, `send` and `recv`
#     are type names only, and stay ordinary identifiers elsewhere
#
# See also: 调用, 通道, 帧, 发送, 接收, 迭代器
# =============================================================================

fn count_items(channel s) → int {
    var int n ← 0
    for from s.recv<string>().cursor() const item {
        print item.data
        n ← n + 1
    }
    return n
}

main {
    const channel s ← call 'runtime:echo' ("salve")
    const send<value> outbound ← s.send<value>()
    outbound.da("ping")
    outbound.fini()
    print count_items(s)

    const channel second ← call 'runtime:echo' ("vale")
    const frame<string> ∪ none first ← second.recv<string>().accipe()
    print first?.data
}

Expected output:

salve
1
vale

radix/corpus/ad/sermo-close.fab (canonical · method)#

A 通道 closes itself when its conversation completes; a pool of many keeps only the unfinished ones open, and close() ends one early and reports its error.

# =============================================================================
# 通道 — a conversation closes itself when it completes; `close()` is early.
# =============================================================================
#
# What this teaches:
#   • Completion closes — when the handler returns (or fails), the 通道
#     releases its handler task and router slot at once, even while its
#     handle still sits in a 映射; the handle keeps reading as its result
#   • A pool of many — finished conversations cost nothing while the pool
#     waits on the rest, so a 映射 of many sermones is cheap
#   • Explicit close — `s.close()` ends a conversation early (a live handler
#     is cancelled, unread frames are dropped) and reports the error the
#     conversation ended with through `⇥ 文本`; it returns `真` when
#     this call closed the handle
#   • Last reference — a 通道 nobody can reach is closed as a safety net,
#     but errors from that automatic close are lost; call `close()` when the
#     error matters
#
# Common mistakes:
#   • expecting close() to wait — a handler still running is cancelled, so
#     read to the end first when its outcome matters
#   • keeping a 通道 inside a reference cycle — a cycle never reaches its
#     last reference, so the compiler warns (WARN031) and it never
#     auto-closes; `close()` it explicitly
#
# See also: 调用, 通道, 接收, 执行, 捕获
# =============================================================================

@ 调用 'numeri:bis'
函数 bis(整数 n) → 整数 {
    返回 n * 2
}

@ 调用 'numeri:numera'
函数 numera(整数 n) 流 → 整数 {
    遍历 范围 0‥n 常量 i {
        让出 i
    }
}

@ 调用 'numeri:defice'
函数 defice(整数 n) → 整数 ⇥ 文本 {
    抛错 "defecit §"(n)
}

函数 求和(列表<整数> partes) → 整数 {
    变量 整数 totum ← 0
    遍历 取自 partes 常量 pars {
        totum ← totum + pars
    }
    返回 totum
}

入口 {
    # Four conversations finish at once; their handles wait in the pool.
    变量 映射<整数, 通道> piscina ← 空集
    遍历 范围 0‥4 常量 i {
        piscina[i] ← 调用 'numeri:bis' (i)
    }

    # A longer conversation streams while the finished ones hold nothing.
    常量 通道 longus ← 调用 'numeri:numera' (5)
    遍历 范围 0‥4 常量 i {
        显示 piscina[i] ↦ 整数
    }
    显示 求和(longus ↦ 列表<整数>)

    # Reading waits for the handler (a failed read defaults to 0); close()
    # then reports the error the conversation ended with.
    常量 通道 小数 ← 调用 'numeri:defice' (7)
    显示 小数 ↦ 整数 ⊥ 0
    执行 {
        常量 布尔 clausa ← fractus.close()
        显示 clausa
    } 捕获 err {
        显示 err
    }

    # Closing early drops the unread reply; a live handler is cancelled.
    执行 {
        常量 通道 ultimus ← 调用 'numeri:bis' (21)
        常量 布尔 clausa ← ultimus.close()
        显示 clausa
    } 捕获 err {
        显示 err
    }
}

Expected output:

0
2
4
6
10
0
defecit 7
verum