亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用接口和反射來定義安全劃分?

如何使用接口和反射來定義安全劃分?

Go
墨色風雨 2023-07-10 16:44:37
我想定義一個安全劃分,例如:func safeDivide(a, b interface{}) interface{} {    if b == 0 {        return 0    }    return a / b}顯然,這個功能是行不通的。我們不能劃分接口。一種解決方案是判斷輸入的類型并進行劃分。switch reflect.ValueOf(x).Kind() {    case reflect.Int:    // balabala...不過看起來多余,我必須處理好每一個案件。那么我是否可以使用反射來保證輸入的類型?我嘗試過reflect.TypeOf()但失敗了。順便說一句,我注意到這一點:a := uint32(0)ifZero(a) // outputs "no"func ifZero(a interface{}) {    if a == 0 {        log.Println("yes")        return    }    log.Println("no")}這意味著 golang 本身無法處理類型問題,對嗎?
查看完整描述

1 回答

?
慕森王

TA貢獻1777條經驗 獲得超3個贊

現在您知道為什么(某些)人們想要在 Go 中使用泛型。:-)

對于這種特殊情況,您最好只編寫一個safeDivideInt函數:

// a/b, but 0 if b == 0

func safeDivideInt(a, b int64) int64 {

? ? if b == 0 {

? ? ? ? return 0

? ? }

? ? return a / b

}

和一個類似的safeDivideUint函數(使用uint64)...并且,如果需要的話,1個safeDivideFloat函數,例如:


func safeDivideFloat(a, b float64) float64 {

? ? // decide if you want 0/0 handled differently

? ? // decide if you want to check for b being Inf or NaN

? ? // etc.

? ? if b == 0 {

? ? ? ? return 0

? ? }

? ? return a / b

}

如果你愿意的話,然后再一次進行復雜的處理。

但是:沒有簡單的方法可以讓 Go 編譯器為您調用其中之一。您可以按照您的方式編寫基于接口的函數,然后對各種參數進行類型切換,但是由于您必須處理所有可能的組合,因此它會變得很長。無論如何減少,組合效應都是痛苦的。使用reflect和 它的 type-kind 接口在這里沒有幫助,因為您仍然有五種int類型,五種uint類型(如果包含 則為六種類型uintptr),兩種float類型和兩種complex類型。(我不清楚在除法函數中允許使用 或UintptrsUnsafePointer?Kind是否有任何意義。)

然而,根據上下文,定義您自己的界面可能更有意義。?這是 Go Playground 上的一個工作玩具示例。我沒有費心放入 Uint 和 Complex 類型。


1請注意,運行時 1.0 / 0.0 是+Inf。Go規范說:

浮點或復數除以零的結果未在 IEEE-754 標準之外指定;是否發生運行時恐慌是特定于實現的。

但 IEEE-754 默認情況下要求 Inf 和 NaN 結果,異常是可選的,所以我認為這意味著 Go 中的默認情況下不會引發異常,也意味著“無恐慌”。

算術異常(默認情況下)需要記錄在“粘性”狀態標志位中。...默認情況下,操作始終根據規范返回結果,而不會中斷計算。例如,1/0 返回 +∞,同時還設置被零除標志位(這個默認值 ∞ 的設計目的是為了在后續操作中使用時經常返回有限結果,因此可以安全地忽略)。


查看完整回答
反對 回復 2023-07-10
  • 1 回答
  • 0 關注
  • 135 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號