

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 選擇工作流程狀態
<a name="state-choice"></a>

**管理狀態和轉換資料**  
了解如何[使用變數在狀態與使用 JSONata 轉換資料之間傳遞資料](workflow-variables.md)。 [ JSONata](transforming-data.md)

`Choice` 狀態 (`"Type": "Choice"`) 會將條件式邏輯新增至狀態機器。

除了大多數[常見的狀態欄位](statemachine-structure.md#amazon-states-language-common-fields)， `Choice` 狀態還包含下列其他欄位。

**`Choices` (必要)**  
[選擇規則](#state-choice-rules)陣列，該陣列可決定狀態機器接下來會轉換到哪個狀態。您必須至少定義一個`Choice`處於 狀態的規則。  
`Choice` 狀態執行時，Step Functions 會評估每個**選擇規則**為 true 或 false。根據結果，Step Functions 會轉換到工作流程中的下一個狀態。

**`Default` (選用、建議)**  
如果沒有**選擇規則**評估為 true，則要轉換為的狀態名稱。

**重要**  
 `Choice` 狀態不支援 `End` 欄位。此外，這類狀態只會在其 `Choices` 欄位內使用 `Next`。  
如果工作流程執行時沒有 **Choices** 評估為 true，且未提供 **Default**，則狀態機器會因*無法從 狀態轉換而*擲回**錯誤**。

## 選擇規則 (JSONata)
<a name="state-choice-rules"></a>

`Choice` 狀態必須具有`Choices`一個欄位，其值為非空白的選擇規則陣列，其中包含使用 JSONata 時的下列欄位：
+ **`Condition` field** – 評估為 true/false 的 JSONata 表達式。
+ **`Next` 欄位** – 必須符合狀態機器中狀態名稱的值。

以下範例會檢查數值是否等於 `1`。

```
{
  "Condition": "{% $foo = 1 %}",
  "Next": "NumericMatchState"
}
```

下列範例會檢查`type`變數是否等於 `local`。

```
{
  "Condition": "{% $type = 'local' %}",
  "Next": "StringMatchState"
}
```

以下範例會檢查字串是否大於 `MyStringABC`。

```
{
  "Condition": "{% $foo > 'MyStringABC' %}",
  "Next": "StringGreaterMatchState"
}
```

下列範例會檢查字串是否不是 null。

```
{
 "Condition" : "{% $possiblyNullValue != null and $possiblyNullValue = 42 %}",
 "Next": "NotNullAnd42"
}
```

## 選擇規則 (JSONPath)
<a name="state-choice-rules-jsonpath"></a>

`Choice` 狀態必須具有`Choices`一個欄位，其值為選擇規則的非空白陣列，該欄位在使用 JSONPath 時包含下列欄位：
+ **比較** – 兩個欄位，指定要比較的輸入變數、比較類型，以及要比較變數的值。選擇規則支援兩個變數之間的比較。在選擇規則中，變數的值可以透過附加`Path`到支援的比較運算子名稱，與狀態輸入的另一個值進行比較。比較中 `Variable`和 路徑欄位的值必須是有效的[參考路徑](amazon-states-language-paths.md#amazon-states-language-reference-paths)。
+ **`Next` 欄位** – 此欄位的值必須符合狀態機器中的狀態名稱。

以下範例會檢查數值是否等於 `1`。

```
{
  "Variable": "$.foo",
  "NumericEquals": 1,
  "Next": "FirstMatchState"
}
```

以下範例會檢查字串是否等於 `MyString`。

```
{
  "Variable": "$.foo",
  "StringEquals": "MyString",
  "Next": "FirstMatchState"
}
```

以下範例會檢查字串是否大於 `MyStringABC`。

```
{
  "Variable": "$.foo",
  "StringGreaterThan": "MyStringABC",
  "Next": "FirstMatchState"
}
```

下列範例會檢查字串是否為 null。

```
{
 "Variable": "$.possiblyNullValue",
 "IsNull": true
}
```

下列範例顯示 StringEquals 規則只有在 `$.keyThatMightNotExist` 存在時，才會因為上述`IsPresent`選擇規則而進行評估。

```
"And": [
 {
 "Variable": "$.keyThatMightNotExist",
 "IsPresent": true
 },
 {
 "Variable": "$.keyThatMightNotExist",
 "StringEquals": "foo"
 }
]
```

下列範例會檢查具有萬用字元的模式是否相符。

```
{
 "Variable": "$.foo",
 "StringMatches": "log-*.txt"
}
```

以下範例會檢查時間戳記是否等於 `2001-01-01T12:00:00Z`。

```
{
  "Variable": "$.foo",
  "TimestampEquals": "2001-01-01T12:00:00Z",
  "Next": "FirstMatchState"
}
```

下列範例會將變數與狀態輸入的另一個值進行比較。

```
{
 "Variable": "$.foo",
 "StringEqualsPath": "$.bar"
}
```

Step Functions 會依 `Choices` 欄位中列出的順序檢查每個選擇規則。然後轉換為第一個「選擇規則」的 `Next` 欄位中指定的狀態，在該規則中變數會根據比較運算子來比對值。

支援下列比較運算子：
+ `And`
+ `BooleanEquals`,`BooleanEqualsPath`
+ `IsBoolean`
+ `IsNull`
+ `IsNumeric`
+ `IsPresent`
+ `IsString`
+ `IsTimestamp`
+ `Not`
+ `NumericEquals`,`NumericEqualsPath`
+ `NumericGreaterThan`,`NumericGreaterThanPath`
+ `NumericGreaterThanEquals`,`NumericGreaterThanEqualsPath`
+ `NumericLessThan`,`NumericLessThanPath`
+ `NumericLessThanEquals`,`NumericLessThanEqualsPath`
+ `Or`
+ `StringEquals`,`StringEqualsPath`
+ `StringGreaterThan`,`StringGreaterThanPath`
+ `StringGreaterThanEquals`,`StringGreaterThanEqualsPath`
+ `StringLessThan`,`StringLessThanPath`
+ `StringLessThanEquals`,`StringLessThanEqualsPath`
+ `StringMatches`
+ `TimestampEquals`,`TimestampEqualsPath`
+ `TimestampGreaterThan`,`TimestampGreaterThanPath`
+ `TimestampGreaterThanEquals`,`TimestampGreaterThanEqualsPath`
+ `TimestampLessThan`,`TimestampLessThanPath`
+ `TimestampLessThanEquals`,`TimestampLessThanEqualsPath`

對於每個運算子，對應的值必須是適當的類型：字串、數字、布林值或時間戳記。Step Functions 不會嘗試將數值欄位與字串值比對。不過，由於時間戳記欄位邏輯上為字串，因此 `StringEquals` 比較子可以比對被視為時間戳記的欄位。

**注意**  
基於相互操作性，請勿假設數字比較適用於 [IEEE 754-2008 `binary64` 資料類型](https://en.wikipedia.org/wiki/IEEE_754#Basic_and_interchange_formats)所代表量級或精確度以外的值。尤其是，範圍 `[-253+1, 253-1]` 之外的整數可能無法以預期的方式進行比較。  
時間戳記 (例如 `2016-08-18T17:33:00Z`) 必須符合 [RFC3339 設定檔 ISO 8601](https://www.ietf.org/rfc/rfc3339.txt)，以及進一步的限制：  
大寫字母 `T` 必須分開日期與時間部分。
大寫字母 `Z` 必須表示不存在數字時間時區位移。
若要了解字串比較行為，請參閱 [Java `compareTo` 文件](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#compareTo-java.lang.String-)。  
`And` 和 `Or` 運算子的值必須是本身不得包含 `Next` 欄位的非空白選擇規則陣列。同樣地，`Not` 運算子的值必須是不得包含 `Next` 欄位的單一選擇規則。  
您可以使用 `And`、`Not` 及 `Or`，建立複雜的巢狀選擇規則。不過，`Next` 欄位只能出現在最上層選擇規則中。  
可以使用 StringMatches 比較運算子執行與具有一或多個萬用字元 (“\$1”) 模式的字串比較。使用標準 逸出萬用字元`\\ (Ex: “\\*”)`。比對期間，除了「\$1」之外，沒有任何字元具有任何特殊意義。