Типы

Как можно предположить по выводу команд explain и help, Toolshed — строго типизированный язык. Система типов, по большей части, совпадает с системой типов C#, хотя Toolshed добавляет некоторые дополнительные правила типов для удобства как пользователей, так и разработчиков. То есть вывод команд — это настоящие типы C#, такие как int, EntityUid или какой-нибудь IEnumerable<T>, а не просто строки. Все команды имеют сигнатуру типа, и эта сигнатура может динамически меняться в зависимости от типа конвейерного значения.

Например, тип, передаваемый по конвейеру в команду сложения +, определяет тип вывода и то, как разбирается аргумент. Например, i 1 + 2 и f 1 + 2.5 — допустимые команды, но в i 1 + 1.5 не удастся разобрать “1.5” как аргумент int.

> explain i 1 + 1

i - Integer constant.
Pipe input: [none]
Pipe output: Int32
Signature:
  i <value (Int32)>

+ - Performs numeric addition.
Pipe input: Int32
Pipe output: Int32
Signature:
  <x> → + <y (Int32)>

> explain f 1 + 1.5

f - Float constant.
Pipe input: [none]
Pipe output: Single
Signature:
  f <value (Single)>

+ - Performs numeric addition.
Pipe input: Single
Pipe output: Single
Signature:
  <x> → + <y (Single)>

> i 1 + 1.5

i 1 + 1.5
      ^^^
The value 1.5 is not a valid Int32.

Типовые аргументы

Некоторые аргументы команд также принимают типовые аргументы. Эти аргументы обычно определяют тип вывода или то, как разбираются некоторые другие аргументы. Типовые аргументы всегда указываются перед любыми другими аргументами, но в остальном выглядят как обычные аргументы. В сигнатурах команд help и explain они отображаются как часть имени команды с использованием синтаксиса дженериков C#, то есть <T>, <T1, T2>.

Например, команда comp:get<T> имеет сигнатуру IEnumerable<EntityUid> -> IEnumerable<T>, где T — любой указанный пользователем компонент. Фактический тип компонента указывается через типовой аргумент:

> help comp:get

comp:get - Gets the given component from the given entity.
Usage:
  <input (IEnumerable<EntityUid>)> → comp:get<T> → IEnumerable<T>
  <input (EntityUid)> → comp:get<T> → T


> explain entities comp:get Item

entities - Returns all entities on the server.
Pipe input: [none]
Pipe output: IEnumerable<EntityUid>
Signature:
  entities

comp:get - Gets the given component from the given entity.
Pipe input: IEnumerable<EntityUid>
Pipe output: IEnumerable<ItemComponent>
Signature:
  <input> → comp:get<ItemComponent>

Для пользователей

Все значения — это список длиной 1 (T -> IEnumerable<T>)

Toolshed автоматически приведёт одиночное значение к списку, содержащему только это значение, если это необходимо. Это позволяет при необходимости применять команды, применимые только к перечислимым значениям, к одиночным значениям.

Любая коллекция T является IEnumerable<T>

Технически это не относится именно к Toolshed, но полезно знать, что можно использовать List<T>, HashSet<T>, Dictionary<K,V> и т. д. в качестве ввода для любой команды, принимающей перечисление.

При присваивании IEnumerable<T> упаковывается в List<T>.

При присваивании перечисления переменной Toolshed автоматически приводит его к списку, чтобы полностью вычислить его и позволить вам использовать его повторно. В C# использовать IEnumerable<T> более одного раза запрещено, отсюда это приведение.

Для разработчиков

Ограничения ковариантности и контравариантности.

Toolshed откажется выполнять сложные проверки присваиваемости для типов с более чем одним ковариантным или контравариантным аргументом, чтобы избежать комбинаторного взрыва при поиске всех возможных типов для использования.

IAsType<T> и неявное приведение.

Toolshed будет считать T допустимым неявным приведением для любого типа, реализующего IAsType<T>. Например, если Foo : IAsType<Bar>, Toolshed использует реализацию IAsType, чтобы получить Bar из Foo, если это позволит успешно проверить типы при выполнении команды.

Subpages