2009-11-25 33 views
7

Tôi đã quen với Chuỗi của Java, nơi chúng ta có thể truyền null thay vì "" cho các ý nghĩa đặc biệt, chẳng hạn như sử dụng giá trị mặc định.Làm thế nào để có một hàm có tham số chuỗi rỗng trong Go?

Trong Go, chuỗi là kiểu nguyên thủy, vì vậy tôi không thể chuyển nil (null) thành tham số yêu cầu chuỗi.

tôi có thể viết các chức năng sử dụng kiểu con trỏ, như thế này:

func f(s *string) 

để người gọi có thể gọi đó là chức năng hoặc là

f(nil) 

hoặc

// not so elegant 
temp := "hello"; 
f(&temp) 

nhưng sau đây là rất tiếc không được phép:

// elegant but disallowed 
f(&"hello"); 

Cách tốt nhất để có tham số nhận chuỗi hoặc số không?

+0

Tôi tin rằng bạn cần phải loại bỏ Java và làm quen với Cách di chuyển. Tại sao bạn cần phải vượt qua một số không thay vì một chuỗi? Bạn muốn đạt được những gì? ps. bạn cũng có thể sử dụng fmt.Printf (* new (string)) - đó là 'zero' cho loại chuỗi –

Trả lời

1

Không thực sự tham dự câu trả lời: nhưng giá trị cong vênh trong cấu trúc có thể cung cấp một số methode tiện ích chung. (Haskell Maybe?)

//#maybe.go 
package maybe 

import "log" 

type MayHaveValue struct { 
IsValue bool; 
} 

func (this MayHaveValue) IsJust() bool { 
return this.IsValue 
} 

type AString struct { 
MayHaveValue; 
Value string; 
} 

func String(aString string) AString { 
return AString{MayHaveValue{true}, aString} 
} 

var NoString AString = AString{MayHaveValue{false}, ""} 

func (this AString) String() (value string) { 
if this.IsJust() == true { 
    value = this.Value; 
} else { 
    log.Crash("Access to non existent maybeString value"); 
} 
return; 
} 

func (this AString) OrDefault(defaultString string) (value string) { 
if this.IsJust() { 
    value = this.Value; 
} else { 
    value = defaultString; 
} 
return; 
} 

//#main.go 
package main 

import "fmt" 
import "maybe" 

func say(canBeString maybe.AString) { 
if canBeString.IsJust() { 
    fmt.Printf("Say : %v\n", canBeString.String()); 
} else { 
    fmt.Print("Nothing to say !\n"); 
} 
} 

func sayMaybeNothing (canBeString maybe.AString) { 
fmt.Printf("Say : %v\n", canBeString.OrDefault("nothing")); 
} 

func main() { 
aString := maybe.String("hello"); 
say(aString); 
sayMaybeNothing(aString); 
noString := maybe.NoString; 
say(noString); 
sayMaybeNothing(noString); 
} 
4

Tôi nghĩ một số chi tiết về làm thế nào tôi sẽ thực hiện điều này bằng cách sử dụng struct. Dưới đây là những gì tôi đã đưa ra:

type MyString struct { 
    val string; 
} 

func f(s MyString) { 
    if s == nil { 
     s = MyString{"some default"}; 
    } 
    //do something with s.val 
} 

Sau đó, bạn có thể gọi f như thế này:

f(nil); 
f(MyString{"not a default"}); 
+1

@DaveC Cảm ơn bạn đã cuối cùng phê bình câu trả lời sáu tuổi của tôi, từ thời điểm Go ít hơn một tuần tuổi. Tôi sợ chúng tôi đã bắt đầu phát triển một nền văn hóa có tính đến bối cảnh trong đó câu trả lời cũ đã được cung cấp. –

+0

Câu hỏi đặt lên đầu danh sách đang hoạt động gần đây và tôi đã xem câu trả lời và thấy câu trả lời không chính xác này. Tôi đã thêm nhận xét để những người khác không lãng phí thời gian để thử giải pháp không được bỏ phiếu này. Ngày không liên quan. (IMO, thay vì bị lén lút, bạn chỉ nên xóa hoặc chỉnh sửa các câu trả lời đầu cơ và không chính xác cho câu hỏi này). –

+0

Mọi nhận xét bạn để lại trên các câu trả lời cho câu hỏi này đều rất láu cá và vô ích. Làm thế nào mà nói đi về chỉ ra các vấn đề mà không đề xuất các giải pháp? Có thể bạn nên xem xét đề xuất chỉnh sửa cho các câu trả lời hiện có hoặc để lại câu trả lời của riêng bạn. (Đối với hậu thế/bối cảnh, DaveC đã để lại một bình luận chỉ trích "câu trả lời" của tôi [trích dẫn của anh ấy] mà không gợi ý nó có thể được cải thiện như thế nào.) –

-3

Loose Java suy nghĩ và chỉ cần vượt qua f (""). Sau đó kiểm tra bằng len():

func f (str string) { nếu len (str)> 0 { ... } else { ... }}

Hoặc là chuỗi trống và có ý nghĩa ngữ nghĩa của trường hợp nil của bạn, hoặc có một số dữ liệu chuỗi để xử lý. Không thể thấy vấn đề với điều đó.

+5

Vấn đề là bạn có thể có chuỗi rỗng như thông số bình thường, không có nghĩa là "mặc định". Những gì bạn đề nghị là "tín hiệu trong băng" (như sử dụng 0 hoặc -1 cho một số nguyên) và được xem là một ý tưởng tồi vì bạn có thể cần giá trị "đặc biệt" cho ý nghĩa thông thường. – bortzmeyer

2

Tôi biết tôi là người siêu muộn với bữa tiệc này, nhưng tôi đã tìm thấy điều này trong khi tìm kiếm một vấn đề tương tự, và nghĩ rằng tôi sẽ thêm giải pháp của mình cho hậu thế.

Tùy thuộc vào trường hợp sử dụng của bạn, sử dụng variadic function có thể là bạn của bạn. Điều này cho phép bạn nhập không hoặc nhiều đối số cùng loại vào một hàm, được nhận trong hàm dưới dạng mảng.

// My variadic function 
func f(s string...) { 
    if length(s) == 0 { 
    // We got a NULL 
    fmt.Println("default value") 
    } else { 
    // We got a value 
    fmt.Println(s[0]) 
    } 
} 

f() // works! 
f("has a value") // works! 

Giải pháp này yêu cầu bạn biết bạn sẽ bị bỏ qua trong khoảng thời gian phát triển; bạn không thể chỉ gọi f(nil) và làm việc đó. Tuy nhiên, nếu đây không phải là vấn đề trong trường hợp sử dụng cụ thể của bạn, nó có thể là một giải pháp rất thanh lịch, không yêu cầu bạn xác định bất kỳ loại dữ liệu bổ sung nào.

+0

Nó không phải ở tất cả các thanh lịch trong đó một người gọi không có ý tưởng họ không nên/không thể làm một cái gì đó như 'f ("gì", "về", "này") '. Chưa kể rằng bạn chỉ có thể sử dụng '...' làm đối số cuối cùng, và rằng đây là một sự lạm dụng tính năng đó. –

Các vấn đề liên quan