ประกาศอาร์เรย์คงที่


164

ฉันเหนื่อย:

const ascii = "abcdefghijklmnopqrstuvwxyz"
const letter_goodness []float32  = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
const letter_goodness  = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
const letter_goodness = []float32 { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }

ขั้นแรกการประกาศและการเริ่มต้นทำงานได้ดี แต่ตัวที่สองสามและสี่ไม่ทำงาน ฉันจะประกาศและเริ่มต้นอาร์เรย์อาร์เรย์ของ const ได้อย่างไร

คำตอบ:


232

อาร์เรย์ไม่สามารถเปลี่ยนแปลงได้โดยธรรมชาติ คุณไม่สามารถทำให้มันคงที่

ที่ใกล้ที่สุดที่คุณจะได้รับคือ:

var letter_goodness = [...]float32 {.0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697, .0015, .0077, .0402, .0241, .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, .0236, .0015, .0197, .0007 }

หมายเหตุ[...]แทน[]: มันช่วยให้คุณได้รับอาร์เรย์ (ขนาดคงที่) แทนที่จะเป็นชิ้น ดังนั้นค่าจะไม่คงที่ แต่ขนาดคือ


126
เพียงเพื่อชี้แจงที่: ไวยากรณ์น้ำตาล[...]T [123]Tมันสร้างอาร์เรย์ขนาดคงที่ แต่ให้คอมไพเลอร์เข้าใจจำนวนองค์ประกอบที่อยู่ในนั้น
jimt

5
ฉันเดาว่าการอนุญาตให้ใช้อาเรย์คงที่จะต้องมีการอัปเดตระบบประเภท มิฉะนั้นถ้าคุณกำหนดฟังก์ชั่นf(xs [5]int)คุณจะไม่ทราบว่าอาเรย์ที่ผ่านนั้นเป็นค่าคงที่หรือไม่แน่นอน
โทมัส Ahle

tks ฉันมีปัญหาเมื่อฉันพยายามที่จะ จำกัด Join cannot use constants.FilesRequired (type [4]string) as type []string in argument to strings.Join
Eddy Hernandez

ขอบคุณสำหรับการแก้ปัญหาชิ้น สงสัย: อาเรย์นั้นไม่เปลี่ยนรูปใช่มั้ย หนึ่งไม่สามารถเพิ่มหรือลบองค์ประกอบเมื่อมีการสร้างอาร์เรย์หรือไม่ อย่างไรก็ตามฉันสามารถแก้ไของค์ประกอบอาร์เรย์ได้
ตำนาน 2k

@ legends2k คุณไม่สามารถเปลี่ยนขนาดของอาร์เรย์ได้ แต่คุณสามารถใส่ค่าอื่น ๆ ลงในช่องได้
Denys Séguret

63

จากการเริ่มต้นที่มีประสิทธิภาพ :

ค่าคงที่ใน Go คือค่าคงที่ พวกเขาจะถูกสร้างขึ้นในเวลารวบรวมแม้เมื่อกำหนดเป็นคนในฟังก์ชั่นและสามารถเป็นตัวเลขสตริงหรือบูลีนเท่านั้น เนื่องจากข้อ จำกัด ในการคอมไพล์เวลานิพจน์ที่กำหนดไว้จะต้องเป็นนิพจน์คงที่ประเมินโดยคอมไพเลอร์ ตัวอย่างเช่น 1 << 3 เป็นนิพจน์คงที่ในขณะที่ math.Sin (math.Pi / 4) ไม่ใช่เพราะการเรียกฟังก์ชันไปที่ math.Sin จำเป็นต้องเกิดขึ้นในเวลาทำงาน

ตัวแบ่งและอาร์เรย์จะถูกประเมินเสมอระหว่างรันไทม์:

var TestSlice = []float32 {.03, .02}
var TestArray = [2]float32 {.03, .02}
var TestArray2 = [...]float32 {.03, .02}

[...]บอกคอมไพเลอร์ให้หาความยาวของอาเรย์เอง ห่ออาร์เรย์และง่ายต่อการใช้งานในกรณีส่วนใหญ่ แทนที่จะใช้ค่าคงที่เพียงทำให้ตัวแปรไม่สามารถเข้าถึงแพ็กเกจอื่นได้โดยใช้อักษรตัวพิมพ์เล็กตัวแรก:

var ThisIsPublic = [2]float32 {.03, .02}
var thisIsPrivate = [2]float32 {.03, .02}

thisIsPrivateมีเฉพาะในแพ็คเกจที่กำหนดไว้เท่านั้น หากคุณต้องการการเข้าถึงแบบอ่านจากภายนอกคุณสามารถเขียนฟังก์ชัน getter แบบง่าย ๆ (ดูที่Getters in golang )


12

ไม่มีสิ่งเช่นค่าคงที่อาร์เรย์ใน Go

การอ้างอิงจากข้อกำหนดภาษา Go: ค่าคงที่ :

มีค่าคงที่บูล , คงคาถา , ค่าคงที่จำนวนเต็ม , ค่าคงที่จุดลอยตัว , ค่าคงที่ที่ซับซ้อนและค่าคงที่สตริง Rune จำนวนเต็มลอยจุดและค่าคงที่ซับซ้อนจะถูกเรียกว่าค่าคงที่เป็นตัวเลข

แสดงออกคงที่ (ซึ่งถูกนำมาใช้ในการเริ่มต้นอย่างต่อเนื่อง) อาจมีเพียงคงถูกดำเนินการและจะมีการประเมินที่รวบรวมเวลา

ข้อมูลจำเพาะแสดงรายการค่าคงที่ประเภทต่าง ๆ โปรดทราบว่าคุณสามารถสร้างและเริ่มต้นคงมีการแสดงออกอย่างต่อเนื่องประเภทมีประเภทใดประเภทหนึ่งที่ได้รับอนุญาตเป็นชนิดพื้นฐาน เช่นนี้ถูกต้อง:

func main() {
    type Myint int
    const i1 Myint = 1
    const i2 = Myint(2)
    fmt.Printf("%T %v\n", i1, i1)
    fmt.Printf("%T %v\n", i2, i2)
}

เอาท์พุท (ลองไปที่สนามเด็กเล่นไป ):

main.Myint 1
main.Myint 2

หากคุณต้องการอาร์เรย์มันสามารถเป็นตัวแปรได้ แต่ไม่ใช่ค่าคงที่

ฉันแนะนำบทความบล็อกที่ยอดเยี่ยมเกี่ยวกับค่าคงที่: ค่าคงที่


ถ้าต้องการภาชนะที่มีขนาดคงที่ต้องทำอย่างไร?

@Atomic_alarm คุณช่วยอธิบายได้ไหม?
icza

มีอยู่ไม่ว่าจะเป็นในอะนาล็อก C-array ของ golang?

@Atomic_alarm ใช่อาร์เรย์มีอยู่ใน Go ด้วยเช่นกันพวกเขาไม่ใช่เพียงนิพจน์คงที่พวกเขาจะถูกประเมินที่ runtime ดังนั้นค่าคงที่ไม่สามารถเป็นชนิดอาร์เรย์ได้ แต่ตัวแปรสามารถ ตัวอย่างเช่น:var arr = [2]int{2, 3}
icza

3

อย่างที่คนอื่น ๆ พูดถึงไม่มีการก่อสร้างอย่างเป็นทางการสำหรับสิ่งนี้ ที่ใกล้ที่สุดที่ฉันจินตนาการได้ก็คือฟังก์ชั่นที่คืนค่าชิ้น ด้วยวิธีนี้คุณสามารถรับประกันได้ว่าจะไม่มีใครจัดการองค์ประกอบของชิ้นต้นฉบับ (เพราะเป็น "ฮาร์ดโค้ด" ในอาร์เรย์)

ฉันทำให้ส่วนของคุณสั้นลงเพื่อให้สั้นลง ... :

func GetLetterGoodness() []float32 {
    return [...]float32 { .0817,.0149,.0278,.0425,.1270,.0223 }
}

4
ดูเหมือนจะเป็นวิธีที่ดีที่สุด แต่ประเภทการคืน func ไม่ตรงกัน cannot use [6]string literal (type [6]string) as type []string in return argumentดังนั้นreturn []float32 { ... }
theRemix

@theRemix สามการแก้ไขที่เป็นไปได้: (1) ลบ...เพื่อประกาศตัวอักษรชิ้นแทนที่จะเป็นตัวอักษรอาร์เรย์ (2) [6]float32การเปลี่ยนประเภทกลับไป (3) กำหนดให้การแสดงออกตัวแปรอาร์เรย์และกลับชิ้นขององค์ประกอบทั้งหมด:a := [...]float32 { (etc.) } return a[:](ตัวอักษรอาร์เรย์ไม่สามารถพูดได้ฉันไม่ชัดเจนว่าทำไม)
David Moles

ฉันไม่แน่ใจว่าสิ่งที่รับประกันคุณหมายถึงอะไร ดูเหมือนว่าคุณพยายามที่จะแก้ปัญหาบางอย่างในรหัสของคุณซึ่งอาจแก้ไขได้ดีกว่าด้วยการทดสอบ (หน่วย -)
Dynom
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.