# 复合类型

> 

## `list<T>`

`list<T>` 是有序序列，元素类型一致。

```dj
let numbers: list<int> = [1, 2, 3];
```

规则：

- 支持下标访问：`xs[i]`
- 支持下标赋值：`xs[i] = v`
- 支持 `push`、`pop`、`remove`、`clear`、`len`
- 越界访问或空列表 `pop()` 时 `panic`
- 更新操作只能作用在 `var` 绑定上

## `map<K, V>`

`map<K, V>` 是键值字典。

```dj
let scores: map<string, int> = { "a": 1, "b": 2 };
```

规则：

- 支持下标访问：`m[k]`
- 支持下标赋值：`m[k] = v`
- 支持 `remove`、`clear`、`contains`、`len`
- `m[k]` 缺 key 时 `panic`
- `m[k] = v` 缺 key 时直接插入
- `remove(k)` 缺 key 时 `panic`

当前 `map` key 只允许：

- `int`
- `bool`
- `rune`
- `string`

## `opt<T>`

`opt<T>` 表示可选值。

构造与判定：

- `none`
- `some(x)`
- `x is none`
- `x is some(v)`

```dj
let title: opt<string> = none;
let count: opt<int> = some(3);
```

规则：

- `opt<T>` 不支持比较
- 参数类型为 `opt<T>` 时允许省略
- 传 `T` 时会自动提升为 `some(T)`

## `iter<T>`

`iter<T>` 是遍历用的中间类型，不是稳定容器。

```dj
let xs: list<int> = [1, 2, 3];
let result = iter(xs).map(func(x: int) -> string {
    `#${x}`
}).collect();
```

规则：

- 可用于 `for x in expr`
- 当前核心操作：

  - `map`
  - `filter`
  - `collect`
- 不支持下标访问
- 更适合作为遍历管道，而不是长期保存的数据值

## `any`

`any` 是边界类型，不是万能类型。

```dj
let props: map<string, any> = { "title": "hello" };
let value = props["title"];

if value is string(s) {
    text(s)
}
```

规则：

- `T -> any` 允许
- `any -> T` 不做隐式恢复
- 当前主要通过 `is` 做显式收窄
- 主要用于 `main(props)`、`element.props` 这类动态边界

## `widget`

`widget` 是抽象渲染结果类型。

```dj
func main() -> widget {
    text("Hello")
}
```

规则：

- `widget` 是一等类型
- 可以赋值、传参、返回
- 可以放入 `list<widget>`
- 不支持比较
- 不作为 `map` key
