Go 繫結

程式庫

假設 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.VMOzx.Channelzx.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() boolfunc (u *User) HasName() bool:檢查時間 藉此判斷該欄位是否存在
  • func (u *User) SetAge(age uint8)func (u *User) SetName(name string): 欄位 setter。
  • func (u *User) GetAge() uint8func (u *User) GetName() string:欄位 getters。
  • func (u *User) GetAgeWithDefault(_default uint8) uint8func (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;
};

TicTacToeWithCtxMakeMove 的方法簽章 介面

MakeMove(ctx_ fidl.Context, row uint8, col uint8) (TicTacToeMakeMoveResult, error)

TicTacToeMakeMoveResult 會以包含兩個變化版本的「聯集」形式產生: Err,也就是 MoveErrorResponse 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 常數,其中包含 通訊協定名稱