Cách khai báo bản đồ hằng


126

Tôi đang cố gắng khai báo thành hằng trong cờ vây, nhưng nó đang gặp lỗi. Bất cứ ai có thể vui lòng giúp tôi với cú pháp khai báo một hằng số trong Go?

Đây là mã của tôi:

const romanNumeralDict map[int]string = {
  1000: "M",
  900 : "CM",
  500 : "D",
  400 : "CD",
  100 : "C",
  90  : "XC",
  50  : "L",
  40  : "XL",
  10  : "X",
  9   : "IX",
  5   : "V",
  4   : "IV",
  1   : "I",
}

Đây là lỗi

# command-line-arguments
./Roman_Numerals.go:9: syntax error: unexpected {

Câu trả lời:


154

Cú pháp của bạn không chính xác. Để tạo một bản đồ chữ (dưới dạng hằng số giả), bạn có thể làm:

var romanNumeralDict = map[int]string{
  1000: "M",
  900 : "CM",
  500 : "D",
  400 : "CD",
  100 : "C",
  90  : "XC",
  50  : "L",
  40  : "XL",
  10  : "X",
  9   : "IX",
  5   : "V",
  4   : "IV",
  1   : "I",
}

Bên trong một funcbạn có thể khai báo nó như sau:

romanNumeralDict := map[int]string{
...

Và trong cờ vây không có thứ gọi là bản đồ bất biến. Thông tin thêm có thể được tìm thấy ở đây .

Hãy chơi thử trên sân chơi cờ vây.


1
Điều này non-declaration statement outside function bodythực sự ném một vào thời gian biên dịch. Làm thế nào mà?
alediaferia

@AlessandroDiaferia Tôi không gặp lỗi như vậy. Bạn sử dụng nó như thế nào?
squiguy

7
@AlessandroDiaferia hãy thử var romanNumeralDict map[int]string = map[int]string{...}trong trường hợp như vậy.
B-Scan

4
@alediaferia bạn gặp lỗi đó nếu sử dụng :=bên ngoài một chức năng.
Jeffrey Martinez

1
"Hằng số giả" là gì?
Garrett

23

Bạn có thể tạo hằng số theo nhiều cách khác nhau:

const myString = "hello"
const pi = 3.14 // untyped constant
const life int = 42 // typed constant (can use only with ints)

Bạn cũng có thể tạo một hằng số enum:

const ( 
   First = 1
   Second = 2
   Third = 4
)

Bạn không thể tạo hằng số của bản đồ, mảng và nó được viết bằng go :

Hằng số trong cờ vây chỉ là vậy — không đổi. Chúng được tạo tại thời điểm biên dịch, ngay cả khi được định nghĩa là cục bộ trong các hàm và chỉ có thể là số, ký tự (rune), chuỗi hoặc boolean. Do giới hạn thời gian biên dịch, các biểu thức xác định chúng phải là biểu thức hằng số, có thể đánh giá được bởi trình biên dịch. Ví dụ, 1 << 3 là một biểu thức hằng, trong khi math.Sin (math.Pi / 4) không phải là vì lệnh gọi hàm math.Sin cần phải xảy ra tại thời điểm chạy.


vì vậy nó giống như một hàm constexpr C ++ 11 ... tại sao math.Sin không phải là một hàm constexpr, vậy!
Francesco Dondi

Tuyên bố của bạn đúng, nhưng câu hỏi về việc tạo một bản đồ là không đổi.
jzer7

5
@ jzer7 bạn có thể giải thích cho tôi lý do tại sao câu trả lời của tôi không liên quan không? Anh ấy hỏi làm thế nào để tạo ra một cái gì đó, tôi nói với anh ấy rằng điều này là không thể. Giải thích những gì có thể và đưa ra một trích dẫn từ các tài liệu tại sao chính xác là không thể làm những gì anh ta muốn.
Salvador Dali

12

Bạn có thể mô phỏng một bản đồ có đóng:

package main

import (
    "fmt"
)

// http://stackoverflow.com/a/27457144/10278

func romanNumeralDict() func(int) string {
    // innerMap is captured in the closure returned below
    innerMap := map[int]string{
        1000: "M",
        900:  "CM",
        500:  "D",
        400:  "CD",
        100:  "C",
        90:   "XC",
        50:   "L",
        40:   "XL",
        10:   "X",
        9:    "IX",
        5:    "V",
        4:    "IV",
        1:    "I",
    }

    return func(key int) string {
        return innerMap[key]
    }
}

func main() {
    fmt.Println(romanNumeralDict()(10))
    fmt.Println(romanNumeralDict()(100))

    dict := romanNumeralDict()
    fmt.Println(dict(400))
}

Hãy thử nó trên sân chơi cờ vây


4
(TestMostSoldRecommender?)
twotwot 2

1
Trên thực tế, nó là một giải pháp khả thi. Tuy nhiên, vì tác giả không giải thích bất cứ điều gì (và đặt mọi thứ bên trong một trường hợp thử nghiệm có tên kỳ lạ) nên câu trả lời có vẻ không chính xác. Logic là: (1) Tạo một hàm ẩn danh (2) Hàm ẩn danh đóng gói map(3) Hàm ẩn danh trả về "một hàm chấp nhận một int và trả về một chuỗi" (4) Hàm trả về thực hiện chuỗi int -> ánh xạ bằng cách sử dụng map(5) Thực thi hàm ẩn danh ngay lập tức và gán hàm trả về cho một biến. Biến này có thể được sử dụng như một hàm và hiệu ứng giống như một bản đồ.
Siu Ching Pong -Asuka Kenji-

3

Và như gợi ý ở trên của Siu Ching Pong -Asuka Kenji với chức năng mà theo tôi là có ý nghĩa hơn và để lại cho bạn sự tiện lợi của loại bản đồ mà không có trình bao bọc chức năng xung quanh:

   // romanNumeralDict returns map[int]string dictionary, since the return
       // value is always the same it gives the pseudo-constant output, which
       // can be referred to in the same map-alike fashion.
       var romanNumeralDict = func() map[int]string { return map[int]string {
            1000: "M",
            900:  "CM",
            500:  "D",
            400:  "CD",
            100:  "C",
            90:   "XC",
            50:   "L",
            40:   "XL",
            10:   "X",
            9:    "IX",
            5:    "V",
            4:    "IV",
            1:    "I",
          }
        }

        func printRoman(key int) {
          fmt.Println(romanNumeralDict()[key])
        }

        func printKeyN(key, n int) {
          fmt.Println(strings.Repeat(romanNumeralDict()[key], n))
        }

        func main() {
          printRoman(1000)
          printRoman(50)
          printKeyN(10, 3)
        }

Hãy thử điều này tại play.golang.org.


-2

Như đã nêu ở trên để xác định một bản đồ là hằng số là không thể. Nhưng bạn có thể khai báo một biến toàn cục là một cấu trúc có chứa bản đồ.

Khởi tạo sẽ giống như sau:

var romanNumeralDict = struct {
    m map[int]string
}{m: map[int]string {
    1000: "M",
    900: "CM",
    //YOUR VALUES HERE
}}

func main() {
    d := 1000
    fmt.Printf("Value of Key (%d): %s", d, romanNumeralDict.m[1000])
}

3
Tại sao không chỉ biến bản đồ thành biến toàn cục? Tại sao lại quấn nó trong cấu trúc?
Bão Hamilton

3
Điều này không làm cho bản đồ liên tục, bạn vẫn có thể làm đượcromanNumeralDict.m[1000] = "New value"
brando
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.