程式庫
假設 library 宣告:
library fuchsia.examples;
繫結程式碼會產生至 examples Go 套件中,
並使用 FIDL 程式庫名稱的最後一個元件。
套件可以使用路徑匯入:
import "fidl/fuchsia/examples"
常數
系統會產生「常數」做為 const 區塊。舉例來說,
下列常數:
const BOARD_SIZE uint8 = 9;
const NAME string = "Tic-Tac-Toe";
產生依據為:
const (
  BoardSize uint8  = 9
  Name      string = "Tic-Tac-Toe"
)
FIDL 原始類型和 Go 類型之間的對應關係列於 內建類型。
欄位
本節說明 FIDL 工具鍊如何將 FIDL 類型轉換為原生類型 在 Go 中輸入文字這些類型可以以會員類型顯示, 新增至通訊協定方法。
內建類型
系統會根據下表將 FIDL 類型轉換為 Go 類型。
| FIDL 類型 | Go 類型 | 
|---|---|
| bool | bool | 
| int8 | int8 | 
| int16 | int16 | 
| int32 | int32 | 
| int64 | int64 | 
| uint8 | uint8 | 
| uint16 | uint16 | 
| uint32 | uint32 | 
| uint64 | uint64 | 
| float32 | float32 | 
| float64 | float64 | 
| array<T, N> | [N]T | 
| vector<T>:N | []T | 
| vector<T>:N? | *[]T | 
| string | string | 
| string:optional | *string | 
| server_end:P | 產生的伺服器端點類型 PInterfaceRequest,請參閱「通訊協定」一節 | 
| client_end:P | 產生的用戶端結束類型 PInterface,請參閱「通訊協定」一節 | 
| 第 zx.Handle:S期、第zx.Handle:<S, optional>期 | 如果 Go 執行階段支援,則會使用對等的處理常式類型 (例如 zx.VMO、zx.Channel和zx.Event)。否則,系統會使用zx.Handle | 
| 第 zx.Handle期、第zx.Handle:optional期 | zx.Handle | 
使用者定義的類型
在 Go 中,使用者定義的類型 (位元、列舉、常數、結構體、聯集或資料表) 為
,請參閱類型定義。
 使用者定義類型 T 的可為空值版本採用指標。
 產生的類型:*T。
類型定義
請注意,本節中產生的 Go 程式碼範例並非表示法 而不是由 FIDL 產生的確切程式碼舉例來說,產生的結構 納入的非匯出欄位無法透過反映檢查。
點數
如果是 bits 定義:
const BOARD_SIZE uint8 = 9;
const NAME string = "Tic-Tac-Toe";
FIDL 會產生基礎類型的類型別名 (如果沒有,則為 uint32)
) 以及每個位元成員的常數:
type FileMode uint16
const (
  FileModeRead    FileMode = 1
  FileModeWrite   FileMode = 2
  FileModeExecute FileMode = 4
  FileMode_Mask   FileMode = 7
)
FileMode_Mask 值是一個位元遮罩,其中包含定義的每個位元成員
FIDL Pod 數量
此外,它還提供下列 FileMode 方法:
- func (x FileMode) String() string:傳回使用者可理解的字串, 位元。
- func (x FileMode) GetUnknownBits() uint64:傳回僅包含的值 從這個位元值取得的不明成員,作為- uint64。一律針對 嚴格位元。
- func (x FileMode) HasUnknownBits() bool:傳回此值是否包含 找出所有未知位元。一律針對嚴格位元傳回- false。
- func (x FileMode) InvertBits() FileMode:反轉所有已知位元。所有語言 將不明位元設為 false
- func (x FileMode) ClearBits(mask FileMode) FileMode:修改位元欄位 這樣系統就會不設定遮罩中的所有位元。
- func (x FileMode) HasBits(mask FileMode) bool:驗證所有翻轉都已完成 設定遮罩
使用範例:
func ExampleFileMode() {
	fmt.Println(examples.FileModeRead.String())
	fmt.Println(examples.FileModeWrite | examples.FileModeExecute)
	// Output:
	// Read
	// Write|Execute
}
列舉
採用 enum 定義:
type LocationType = strict enum {
    MUSEUM = 1;
    AIRPORT = 2;
    RESTAURANT = 3;
};
FIDL 會產生基礎類型的類型別名 (如果沒有,則為 uint32)
) 和常數:
type LocationType uint32
const (
  LocationTypeMuseum     LocationType = 1
  LocationTypeAirport    LocationType = 2
  LocationTypeRestaurant LocationType = 3
)
如果 LocationType 為「彈性」,就會發生不明錯誤
預留位置成員:
    LocationType_Unknown LocationType = 0x7fffffff
如果列舉中有以 [Unknown] 屬性標記的成員,
產生的不明變數值會與已標記的未知變數相同
成員。
LocationType 提供以下方法:
- func (x LocationType) IsUnknown() bool:傳回這個列舉值是否為 未知。針對嚴格列舉,一律傳回- false。
- func (x LocationType) String() string:傳回使用者可理解的字串 列舉。
使用範例:
func ExampleLocationType() {
	fmt.Println(examples.LocationTypeMuseum.String())
	// Output: Museum
}
Structs
假設有 struct 宣告:
type Color = struct {
    id uint32;
    @allow_deprecated_struct_defaults
    name string:MAX_STRING_LENGTH = "red";
};
FIDL 工具鍊會產生含有相符欄位的 Color 結構:
type Color struct {
  Id   uint32
  Name string
}
Go 繫結目前不支援結構欄位的預設值。
使用範例:
func ExampleColor() {
	red := examples.Color{Id: 1, Name: "ruby"}
	fmt.Println(red.Id)
	fmt.Println(red.Name)
	// Output:
	// 1
	// ruby
}
聯合工會
以聯集定義為例:
type JsonValue = strict union {
    1: int_value int32;
    2: string_value string:MAX_STRING_LENGTH;
};
FIDL 會產生別名及代表 union 標記:
type I_jsonValueTag uint64
const (
  JsonValueIntValue     = 2
  JsonValueStringValue  = 3
)
以及含有標記和每個欄位欄位的 JsonValue 結構
聯集的 variant:
type JsonValue struct {
  I_jsonValueTag
  IntValue       int32
  StringValue    string
}
JsonValue 提供以下方法:
- func (_m *JsonValue) Which() I_jsonValueTag:傳回聯集標記。
- func (_m *JsonValue) SetIntValue(intValue int32)和- func (_m *JsonValue) SetStringValue(stringValue string):將聯集設為包含特定 變數,並據此更新代碼。
如果 JsonValue 為「彈性」,則內容如下:
其他方法:
- func (_m *JsonValue) GetUnknownData() fidl.UnknownData:傳回原始值 以及處理未知資料的容器帳號代碼部分會傳回 遍歷順序,而且如果聯集的值保證會留空, 「資源」類型。
FIDL 工具鍊也會產生用於建構執行個體的工廠函式
/JsonValue:
- func JsonValueWithIntValue(intValue int32) JsonValue
- func JsonValueWithStringValue(stringValue string) JsonValue
使用範例:
func ExampleJsonValue() {
	val := examples.JsonValueWithStringValue("hi")
	fmt.Println(val.Which() == examples.JsonValueStringValue)
	fmt.Println(val.StringValue)
	val.SetIntValue(1)
	fmt.Println(val.Which() == examples.JsonValueIntValue)
	fmt.Println(val.IntValue)
	// Output:
	// true
	// hi
	// true
	// 1
}
彈性聯集和未知的變體
彈性聯集在產生的標記中具有額外變化版本 類別:
const (
  JsonValue_unknownData = 0
  // other tags omitted...
)
當 FIDL 訊息含有不明變體的聯集時,解碼成
JsonValue、.Which() 會傳回 JsonValue_unknownData。
將含有未知變體的聯集編碼寫入未知的資料,並 再次接上電線
在解碼未知的變體時,Strict 聯集會失敗。 彈性值類型的聯集會在發生時失敗 使用控點即可解碼未知的變體。
表格
採用下列資料表定義:
type User = table {
    1: age uint8;
    2: name string:MAX_STRING_LENGTH;
};
FIDL 工具鍊會產生 User 結構體,每個結構體都有可用欄位
欄位:
type User struct {
  Age         uint8
  AgePresent  bool
  Name        string
  NamePresent bool
}
User 提供以下方法:
- func (u *User) HasAge() bool和- func (u *User) HasName() bool:檢查時間 藉此判斷該欄位是否存在
- func (u *User) SetAge(age uint8)和- func (u *User) SetName(name string): 欄位 setter。
- func (u *User) GetAge() uint8和- func (u *User) GetName() string:欄位 getters。
- func (u *User) GetAgeWithDefault(_default uint8) uint8和- func (u *User) GetNameWithDefault(_default string) string:傳回 指定的預設值。
- func (u *User) ClearAge()和- func (u *User) ClearName():清除 其作用方式
- func (u *User) HasUnknownData() bool:檢查是否存在不明 只要使用來自這些領域的 小型資料集訓練即可
- func (u *User) GetUnknownData() map[uint64]fidl.UnknownData:傳回地圖 並處理任何不明欄位。帳號代碼清單 如果傳回的是遍歷順序,如果空白,也保證空白 該資料表屬於值類型。
使用範例:
func ExampleUser() {
	var user examples.User
	fmt.Println(user.HasAge(), user.HasName())
	user.SetAge(30)
	user.SetName("John")
	fmt.Println(user.GetAge(), user.GetName())
	user.ClearAge()
	user.ClearName()
	fmt.Println(user.HasAge(), user.HasName())
	fmt.Println(user.GetNameWithDefault("Unknown"))
	// Output:
	// false false
	// 30 John
	// false false
	// Unknown
}
內嵌版面配置
產生的 Go 程式碼會使用 fidlc 保留的名稱,供
內嵌版面配置。
通訊協定
指定通訊協定之後:
closed protocol TicTacToe {
    strict StartGame(struct {
        start_first bool;
    });
    strict MakeMove(struct {
        row uint8;
        col uint8;
    }) -> (struct {
        success bool;
        new_state box<GameState>;
    });
    strict -> OnOpponentMove(struct {
        new_state GameState;
    });
};
FIDL 會產生 TicTacToeWithCtx 介面,供用戶端用於
透過 Proxy 向伺服器發出呼叫,以及由伺服器實作通訊協定:
type TicTacToeWithCtx interface {
  StartGame(ctx_ fidl.Context, startFirst bool) error
  MakeMove(ctx_ fidl.Context, row uint8, col uint8) (bool, *GameState, error)
}
每個方法都會先使用 Context 做為第一個引數,後面接著要求
參數。火災和清除方法會傳回 error,而兩種方法會傳回
回應參數後面加上 error。
與 TicTacToe 通訊協定互動的進入點如下
函式:
func NewTicTacToeWithCtxInterfaceRequest() (TicTacToeWithCtxInterfaceRequest, *TicTacToeWithCtxInterface, error)
這個函式會建立管道,並傳回 TicTacToeWithCtxInterfaceRequest
繫結至管道的一端,代表伺服器端,
TicTacToeWithCtxInterface,繫結至另一端,代表用戶端
結尾。詳情請參閱用戶端和伺服器說明。
專區。
用戶端
用來透過 TicTacToe 通訊協定通訊的管道用戶端
是 TicTacToeWithCtxInterface。實作 TicTacToeWithCtx
「通訊協定」中說明的介面,以及處理方法
事件。請注意,在本實作中,方法呼叫為
同步並封鎖,直到收到回應為止。
您可以在 //examples/fidl/go/client 找到 Go FIDL 用戶端範例。
伺服器
執行這個 FIDL 通訊協定的伺服器時,需要提供具體的
實作 TicTacToeWithCtx 介面。
繫結會產生 TicTacToeWithCtxInterfaceRequest 類型,
代表透過 TicTacToe 通訊管道的伺服器端
因此效能相當卓越它提供以下方法:
- func (c EchoWithCtxInterfaceRequest) ToChannel() zx.Channel:轉換 介面要求傳回未類型管道。
您可以在 //examples/fidl/go/server 找到 Go FIDL 伺服器的範例。
活動
用戶端
TicTacToeWithCtxInterface 提供處理事件的方法:
- func (p *TicTacToeWithCtxInterface) ExpectOnOpponentMove(ctx_ fidl.Context) (GameState, error):- OnOppponentMove的事件處理常式,- Context並傳回事件參數。
呼叫任何事件處理常式方法後,會讀取下一個緩衝事件,或是 區塊,直到接收端為止 - 呼叫端應清空事件緩衝區 立即避免 FIDL 繫結中無限制的緩衝處理。如果下一次事件 與呼叫的方法相符,就會傳回其參數。否則, 錯誤。客戶可自行確保收到的 事件會與已處理事件的順序相符。
伺服器
伺服器可以使用提供的 TicTacToeEventProxy 傳送事件
方法。
- func (p *TicTacToeEventProxy) OnOpponentMove(newState GameState) error:傳送- OnOpponentMove事件。
建立 TicTacToeEventProxy 時,需要存取用戶端的管道。
Go 伺服器範例說明如何取得
EventProxy
結果
Go 繫結不會對含有錯誤類型的方法執行任何特殊處理。
假設方法含有錯誤類型:
protocol TicTacToe {
    MakeMove(struct {
      row uint8;
      col uint8;
    }) -> (struct {
      new_state GameState;
    }) error MoveError;
};
TicTacToeWithCtx 上 MakeMove 的方法簽章
介面:
MakeMove(ctx_ fidl.Context, row uint8, col uint8) (TicTacToeMakeMoveResult, error)
TicTacToeMakeMoveResult 會以包含兩個變化版本的「聯集」形式產生:
Err,也就是 MoveError,Response
TicTacToeMakeMoveResponse。
TicTacToeMakeMoveResponse 會以包含欄位的「結構」的形式產生
對應回應在這個例子中,其中包含
GameState 類型的單一 NewState 欄位。
通訊協定組合
FIDL 沒有繼承的概念,而會產生完整的程式碼做為 以上說明適用於所有編寫的通訊協定。於 也就是程式碼產生的
protocol A {
    Foo();
};
protocol B {
    compose A;
    Bar();
};
提供的 API 與為以下項目產生的程式碼相同:
protocol A {
    Foo();
};
protocol B {
    Foo();
    Bar();
};
產生的程式碼會相同,但方法序數除外。
通訊協定和方法屬性
不透明
為了在 Go 中支援 @transitional 屬性,FIDL 會產生
TicTacToeWithCtxTransitionalBase 類型,提供預設實作方式
針對每個標示為 @transitional 的方法展開測試嵌入
TicTacToeWithCtxTransitionalBase 將繼續建立新的轉場效果
方法。
可供偵測
標示為 @discoverable 時,產生的 InterfaceRequest 類型 (在這個例子中為
範例 TicTacToeWithCtxInterfaceRequest) 導入 fidl.ServiceRequest,
這可以讓伺服器端用於服務探索中。
此外,FIDL 會產生 TicTacToeName 常數,其中包含
通訊協定名稱