程式庫
假設 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
:反轉所有已知位元。所有語言 將不明位元設為 falsefunc (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
常數,其中包含
通訊協定名稱