iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
佛心分享-SideProject30

用 Golang 實作 streamlit 系列 第 26

Day26 Function Overload for Components

  • 分享至 

  • xImage
  •  

參考 Streamlit 的 Component Create Function,我們也需要為 Component 的函數提供多種參數選項。雖然 Golang 本身並不直接支持 Overload ,但我們仍有幾種方法來實現類似的功能,其中最常見的兩種是 Option Pattern 和 Config Pattern。

Option Pattern

Option Pattern 的核心思想是通過一系列函數來表示不同的參數選項,這些函數通常以 WithXXX 的形式命名。使用時,我們可以將這些函數作為參數傳遞給目標函數。這種方式靈活且可擴展:

func Foo(options ...Option) {
  // ...
}

bar.Foo(
  bar.WithTimeout(123),
  bar.WithLength(789),
)
  • 優點:
    • 靈活可擴展: 可以方便地添加新的參數選項。
    • 可讀性較好: 函數調用方式直觀。
  • 缺點 (尤其是在 ToolGUI 底下):
    • 重複: 如果有多個 Component 共享相同的參數選項,會導致重複的 Code。
    • 命名衝突: 當多個 Component 都使用 Option Pattern 時,容易發生命名衝突。

但就 ToolGUI 目前的架構,export 的 Function / Struct 越多,Duplicate 的部分就越多。

而且目前多個 Component 都在同一個 package,假如每個 component 都要有 Option ,又要避免撞名,可能會變成:

tgcomp.Textbox(...,
  tgcomp.TextboxWithXXX(?),
  tgcomp.TextboxWithYYY(?))

也就是說,WithXXX 前面還會再多 Component Name。

Config Pattern

Config Pattern 則將所有參數選項塞到一個 Struct 中。使用時,我們只需要傳遞這個 Struct 作為參數即可。

tgcomp.Textbox(..., &tgcomp.TextboxConf{
  // ...
})
  • 優點:
    • 簡潔: 減少了函數調用的複雜性。
    • 減少命名衝突: 參數選項都在一個 struct 內,避免了命名衝突。
  • 缺點:
    • 靈活性較差: 添加新的參數選項需要修改 struct 。

選擇

經過比較,我選擇了 Config Pattern。這種方式在 ToolGUI 的現有架構下,可以有效減少重複代碼,並避免命名衝突。

我嘗試將 Config Pattern 應用於之前的一些 Component,並添加了一些新的參數,效果不錯。

type DownloadButtonConf struct {
	// MIME specifies the Multipurpose Internet Mail Extension (MIME) type of the downloaded content.
	// Defaults to "application/octet-stream" if not provided.
	MIME string

	// Color defines the color of the download button.
	Color tcutil.Color

	// Disabled indicates whether the download button should be initially disabled.
	Disabled bool

	// Filename sets the suggested filename for the downloaded content when clicked.
	Filename string

	ID string
}

// DownloadButton create a download button component.
func DownloadButton(c *tgframe.Container, text string, body []byte) {
	DownloadButtonWithConf(c, text, body, nil)
}

// DownloadButtonWithConf create a download button component with a user specific config.
// If no configuration is provided, a new one with default values is used.
func DownloadButtonWithConf(c *tgframe.Container, text string,
    body []byte, conf *DownloadButtonConf) {
    // ...
}

參考資料


上一篇
Day25 Sidebar
下一篇
Day27 Local App: Webview
系列文
用 Golang 實作 streamlit 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言