Giá trị mặc định trong phương thức của Go


100

Có cách nào để chỉ định giá trị mặc định trong hàm của Go không? Tôi đang cố gắng tìm điều này trong tài liệu nhưng tôi không thể tìm thấy bất kỳ điều gì xác định rằng điều này thậm chí có thể.

func SaySomething(i string = "Hello")(string){
...
}

Câu trả lời:



119

KHÔNG, nhưng có một số tùy chọn khác để triển khai giá trị mặc định. Có một số bài đăng trên blog hay về chủ đề này, nhưng đây là một số ví dụ cụ thể.


** Tùy chọn 1: ** Người gọi chọn sử dụng các giá trị mặc định
// Both parameters are optional, use empty string for default value
func Concat1(a string, b int) string {
  if a == "" {
    a = "default-a"
  }
  if b == 0 {
    b = 5
  }

  return fmt.Sprintf("%s%d", a, b)
}

** Tùy chọn 2: ** Một thông số tùy chọn duy nhất ở cuối
// a is required, b is optional.
// Only the first value in b_optional will be used.
func Concat2(a string, b_optional ...int) string {
  b := 5
  if len(b_optional) > 0 {
    b = b_optional[0]
  }

  return fmt.Sprintf("%s%d", a, b)
}

** Tùy chọn 3: ** Một cấu trúc cấu hình
// A declarative default value syntax
// Empty values will be replaced with defaults
type Parameters struct {
  A string `default:"default-a"` // this only works with strings
  B string // default is 5
}

func Concat3(prm Parameters) string {
  typ := reflect.TypeOf(prm)

  if prm.A == "" {
    f, _ := typ.FieldByName("A")
    prm.A = f.Tag.Get("default")
  }

  if prm.B == 0 {
    prm.B = 5
  }

  return fmt.Sprintf("%s%d", prm.A, prm.B)
}

** Tùy chọn 4: ** Phân tích cú pháp đối số đa dạng đầy đủ (kiểu javascript)
func Concat4(args ...interface{}) string {
  a := "default-a"
  b := 5

  for _, arg := range args {
    switch t := arg.(type) {
      case string:
        a = t
      case int:
        b = t
      default:
        panic("Unknown argument")
    }
  }

  return fmt.Sprintf("%s%d", a, b)
}

92
Thật là một nỗi đau. Tôi ước nó là: func Concat1(a string = 'foo', b int = 10) string {giống như trong hầu hết các ngôn ngữ hiện đại khác ... Nó sẽ giảm bất kỳ ví dụ nào trong số các ví dụ đã cho xuống khá nhiều thành một dòng mã.
Rotareti,

Chúng ta có tùy chọn viết hai hàm khác nhau và để người gọi trình bày rõ ràng về những gì họ mong đợi.
ProgramCpp

@ProgramCpp không, golang không cho phép nạp chồng hàm Ngôn ngữ Go có nạp chồng hàm / phương thức không?
Vusal

10

Không, không có cách nào để chỉ định giá trị mặc định. Tôi tin rằng điều này được thực hiện có mục đích để nâng cao khả năng đọc, với chi phí là thêm một chút thời gian (và hy vọng là suy nghĩ) về phía người viết.

Tôi nghĩ rằng cách tiếp cận thích hợp để có "mặc định" là có một chức năng mới cung cấp chức năng mặc định cho chức năng chung chung hơn. Có được điều này, mã của bạn trở nên rõ ràng hơn về ý định của bạn. Ví dụ:

func SaySomething(say string) {
    // All the complicated bits involved in saying something
}

func SayHello() {
    SaySomething("Hello")
}

Với rất ít nỗ lực, tôi đã tạo ra một hàm thực hiện một công việc phổ biến và sử dụng lại hàm chung. Bạn có thể thấy điều này trong nhiều thư viện, fmt.Printlnchẳng hạn như chỉ cần thêm một dòng mới cho những gì fmt.Printsẽ làm. Tuy nhiên, khi đọc mã của ai đó, rõ ràng họ định làm gì bằng chức năng mà họ gọi. Với các giá trị mặc định, tôi sẽ không biết điều gì sẽ xảy ra nếu không vào hàm để tham chiếu giá trị mặc định thực sự là gì.


Tôi thích và đồng ý với câu trả lời này nhưng chết tiệt, tôi vẫn ước rằng ít nhất họ có một cách làm khó hiểu nhưng thành ngữ.
Samoena

12
Đối số "chỉ thêm một hàm khác" có thể dẫn đến sự bùng nổ của các phương thức cần thiết để xử lý nhiều hoán vị, yêu cầu gánh nặng quyết định các tên có ý nghĩa, có thể khám phá và dễ nhớ cho các phương thức đó và thêm gánh nặng khi học các gói sử dụng nhiều phương thức hơn so với . ít hơn. #jmtcw
MikeSchinkel Ngày
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.