☰ Mục lục series
Tài liệu Go tiếng Việt
  1. Bắt đầu (Getting started)
    1. Tổng quan
    2. Tải về và cài đặt
    3. Bắt đầu với Go
    4. Quản lý các bản cài đặt Go
    5. Plugin trình soạn thảo và IDE
  2. Dạo quanh Go (A Tour of Go)
    1. Chào mừng
    2. Package, biến và hàm
    3. Điều khiển luồng
    4. Struct, slice và map
    5. Method và interface
    6. Generics
    7. Xử lý đồng thời
  3. Hướng dẫn (Tutorials)
    1. Danh sách hướng dẫn
    2. Tạo một Go module
    3. Gọi mã của bạn từ một module khác
    4. Trả về và xử lý lỗi
    5. Trả về lời chào ngẫu nhiên
    6. Trả về lời chào cho nhiều người
    7. Thêm một test
    8. Biên dịch và cài đặt ứng dụng
    9. Kết luận
    10. Bắt đầu với workspace nhiều module
    11. Phát triển RESTful API với Go và Gin
    12. Truy cập cơ sở dữ liệu quan hệ
    13. Bắt đầu với generics
    14. Bắt đầu với fuzzing
    15. Làm việc với JSON
    16. Tìm và sửa các dependency có lỗ hổng với govulncheck
    17. Tìm và khắc phục phụ thuộc có lỗ hổng với VS Code Go
    18. Viết ứng dụng web
  4. Viết code Go
    1. Cách viết mã Go
    2. Effective Go
    3. Doc Comment trong Go
  5. Module
    1. Phát triển và publish module
    2. Quản lý phụ thuộc
    3. Tổ chức một module Go
    4. Quản lý mã nguồn của module
    5. Cách đánh số phiên bản module
    6. Quy trình phát hành và đánh phiên bản module
    7. Publish một module
    8. Phát triển một bản cập nhật major version
    9. Tham chiếu tệp go.mod
    10. Ngừng hỗ trợ 'go get' cho việc cài đặt tệp thực thi
  6. Cơ sở dữ liệu (Database)
    1. Truy cập cơ sở dữ liệu quan hệ
    2. Mở một handle cơ sở dữ liệu
    3. Thực thi câu lệnh SQL không trả về dữ liệu
    4. Truy vấn dữ liệu
    5. Dùng prepared statement
    6. Thực thi transaction
    7. Huỷ các thao tác đang chạy
    8. Quản lý kết nối
    9. Tránh rủi ro SQL injection
  7. Chẩn đoán và hiệu năng
    1. Chẩn đoán
    2. Hướng dẫn về Go Garbage Collector
    3. Tối ưu hoá dựa trên profile
    4. Data Race Detector
    5. Gỡ lỗi mã Go bằng GDB
    6. Hỗ trợ coverage profiling cho integration test
  8. Bảo mật (Security)
    1. Tổng quan bảo mật
    2. Thực hành tốt về bảo mật cho lập trình viên Go
    3. Quản lý lỗ hổng trong Go
    4. Cơ sở dữ liệu lỗ hổng của Go
    5. Quét lỗ hổng trong IDE
    6. Chính sách CNA của Go
    7. Go Fuzzing
    8. Chi tiết kỹ thuật của Go Fuzzing
    9. Chính sách bảo mật của Go
    10. Threat Model của Go
    11. Các quyết định về bảo mật của Go
    12. Tuân thủ FIPS 140-3
  9. Công cụ và toolchain
    1. Tài liệu về các lệnh
    2. Về lệnh go
    3. Go Toolchains
    4. Telemetry của Go
    5. Cài đặt Go từ mã nguồn
    6. Cài đặt và sử dụng gccgo
  10. Tham khảo
    1. Câu hỏi thường gặp (FAQ)
    2. Go 1 và tương lai của các chương trình Go
    3. Hướng dẫn chuyển đổi sang encoding/json/v2
    4. Hướng dẫn đóng góp
    5. Đóng góp cho frontend gccgo
  11. Phụ lục
    1. Bảng thuật ngữ
Tham khảo

Go 1 và tương lai của các chương trình Go

Bản dịch từ go.dev/doc/go1compat

Giới thiệu

Bản phát hành Go phiên bản 1, gọi tắt là Go 1, là một cột mốc lớn trong quá trình phát triển của ngôn ngữ. Go 1 là một nền tảng ổn định cho sự phát triển của các chương trình và dự án viết bằng Go.

Go 1 định nghĩa hai thứ: thứ nhất, specification của ngôn ngữ; và thứ hai, specification của một tập các API lõi, tức các “standard package” của thư viện Go. Bản phát hành Go 1 bao gồm phần hiện thực của chúng dưới dạng hai bộ compiler (gc và gccgo), cùng bản thân các thư viện lõi.

Chủ đích là các chương trình viết theo specification của Go 1 sẽ tiếp tục biên dịch và chạy đúng, không cần sửa đổi, trong suốt vòng đời của specification đó. Vào một thời điểm chưa xác định, có thể sẽ xuất hiện specification cho Go 2, nhưng cho tới lúc đó, các chương trình Go chạy được hôm nay sẽ tiếp tục chạy được ngay cả khi có thêm các bản phát hành “point” tương lai của Go 1 (Go 1.1, Go 1.2, v.v.).

Tương thích ở mức mã nguồn. Tương thích ở mức binary cho các package đã biên dịch thì không được bảo đảm giữa các bản phát hành. Sau một bản phát hành point, mã nguồn Go sẽ cần được biên dịch lại để liên kết với bản phát hành mới.

Các API có thể lớn thêm, có thêm package và tính năng mới, nhưng không theo cách làm hỏng mã Go 1 hiện có.

Những gì có thể kỳ vọng

Mặc dù chúng tôi kỳ vọng rằng đại đa số chương trình sẽ giữ được tính tương thích này theo thời gian, không thể bảo đảm rằng không thay đổi nào trong tương lai sẽ làm hỏng bất kỳ chương trình nào. Tài liệu này là một nỗ lực nhằm xác lập kỳ vọng về tính tương thích của phần mềm Go 1 trong tương lai. Có một số cách mà một chương trình hôm nay biên dịch và chạy được lại có thể không còn như vậy sau một bản phát hành point trong tương lai. Tất cả đều khó xảy ra nhưng đáng được ghi lại.

  • Bảo mật. Một vấn đề bảo mật trong specification hoặc trong phần hiện thực có thể lộ ra mà cách khắc phục đòi hỏi phá vỡ tính tương thích. Chúng tôi giữ quyền xử lý những vấn đề bảo mật như vậy.
  • Hành vi không được đặc tả. Specification của Go cố gắng nói rõ về hầu hết các tính chất của ngôn ngữ, nhưng có một số khía cạnh không được định nghĩa. Các chương trình phụ thuộc vào những hành vi không được đặc tả đó có thể hỏng trong các bản phát hành tương lai.
  • Lỗi trong specification. Nếu cần phải xử lý một điểm không nhất quán hoặc thiếu sót trong specification, việc giải quyết vấn đề đó có thể ảnh hưởng tới ý nghĩa hoặc tính hợp lệ của các chương trình hiện có. Chúng tôi giữ quyền xử lý những vấn đề như vậy, kể cả việc cập nhật các phần hiện thực. Ngoại trừ các vấn đề bảo mật, sẽ không có thay đổi nào không tương thích được thực hiện với specification.
  • Lỗi. Nếu một compiler hoặc thư viện có lỗi vi phạm specification, một chương trình phụ thuộc vào hành vi lỗi đó có thể hỏng khi lỗi được sửa. Chúng tôi giữ quyền sửa những lỗi như vậy.
  • Struct literal. Để bổ sung tính năng trong các bản phát hành point về sau, có thể cần thêm trường vào các struct được export trong API. Mã dùng struct literal không có khoá (chẳng hạn pkg.T{3, “x”}) để tạo giá trị thuộc những kiểu này sẽ không biên dịch được sau một thay đổi như vậy. Tuy nhiên, mã dùng literal có khoá (pkg.T{A: 3, B: “x”}) sẽ tiếp tục biên dịch được sau thay đổi đó. Chúng tôi sẽ cập nhật những cấu trúc dữ liệu như vậy theo cách cho phép struct literal có khoá vẫn tương thích, dù literal không có khoá có thể không biên dịch được. (Cũng có những trường hợp rắc rối hơn liên quan tới cấu trúc dữ liệu lồng nhau hoặc interface, nhưng cách giải quyết vẫn thế.) Vì vậy chúng tôi khuyến nghị rằng các composite literal có kiểu được định nghĩa trong một package khác thì nên dùng ký pháp có khoá.
  • Method. Cũng như với trường của struct, có thể cần thêm method vào các kiểu không phải interface. Trong một số trường hợp, chẳng hạn khi kiểu đó được embed vào một struct cùng với một kiểu khác, việc thêm method mới có thể làm hỏng struct đó do tạo ra xung đột với một method sẵn có của kiểu được embed kia. Chúng tôi không thể phòng ngừa trường hợp hiếm gặp này và không bảo đảm tính tương thích nếu nó xảy ra.
  • Dot import. Nếu một chương trình import một standard package bằng import . "path", những tên được định nghĩa thêm trong package được import ở các bản phát hành tương lai có thể xung đột với các tên khác được định nghĩa trong chương trình. Chúng tôi không khuyến nghị dùng import . ngoài phạm vi test, và việc dùng nó có thể khiến một chương trình không biên dịch được ở các bản phát hành tương lai.
  • Việc dùng package unsafe. Các package import unsafe có thể phụ thuộc vào các tính chất nội bộ của phần hiện thực Go. Chúng tôi giữ quyền thực hiện những thay đổi trong phần hiện thực có thể làm hỏng những chương trình như vậy.

Dĩ nhiên, với tất cả những khả năng đó, nếu chúng xảy ra, chúng tôi sẽ nỗ lực hết sức khi khả thi để cập nhật specification, compiler hoặc thư viện mà không ảnh hưởng tới mã hiện có.

Chính những cân nhắc này cũng áp dụng cho các bản phát hành point kế tiếp nhau. Ví dụ, mã chạy được dưới Go 1.2 sẽ tương thích với Go 1.2.1, Go 1.3, Go 1.4, v.v., dù không nhất thiết tương thích với Go 1.1 vì nó có thể dùng những tính năng chỉ được thêm vào ở Go 1.2

Các tính năng được thêm vào giữa các bản phát hành, có sẵn trong repository mã nguồn nhưng chưa thuộc các bản phát hành binary có đánh số, là đang trong quá trình phát triển tích cực. Không có cam kết tương thích nào cho phần mềm dùng những tính năng đó cho tới khi chúng được phát hành.

Cuối cùng, dù đây không phải vấn đề về tính đúng đắn, có khả năng hiệu năng của một chương trình bị ảnh hưởng bởi những thay đổi trong phần hiện thực của các compiler hoặc thư viện mà nó phụ thuộc vào. Không thể bảo đảm điều gì về hiệu năng của một chương trình cụ thể giữa các bản phát hành.

Dù những kỳ vọng này áp dụng cho chính Go 1, chúng tôi hy vọng những cân nhắc tương tự cũng sẽ được áp dụng cho việc phát triển phần mềm bên ngoài xây dựng trên nền Go 1.

Các sub-repository

Mã trong các sub-repository của cây go chính, chẳng hạn golang.org/x/net, có thể được phát triển theo những yêu cầu tương thích lỏng hơn. Tuy nhiên, các sub-repository sẽ được gắn tag phù hợp để nhận diện những phiên bản tương thích với các bản phát hành point của Go 1.

Hệ điều hành

Không thể bảo đảm tương thích dài hạn với các giao diện của hệ điều hành, vốn bị thay đổi bởi các bên bên ngoài. Do đó package syscall nằm ngoài phạm vi các bảo đảm nêu ở đây. Kể từ Go phiên bản 1.4, package syscall bị đóng băng. Mọi tiến hoá của giao diện system call phải được hỗ trợ ở nơi khác, chẳng hạn trong subrepository go.sys. Để biết chi tiết và bối cảnh, xem tài liệu này.

Công cụ

Cuối cùng, toolchain của Go (compiler, linker, công cụ build, v.v.) đang trong quá trình phát triển tích cực và có thể thay đổi hành vi. Điều này nghĩa là, chẳng hạn, các script phụ thuộc vào vị trí và tính chất của các công cụ có thể bị hỏng bởi một bản phát hành point.

Bỏ qua những lưu ý đó, chúng tôi tin rằng Go 1 sẽ là một nền tảng vững chắc cho sự phát triển của Go và hệ sinh thái của nó.

Nội dung gốc: Go Documentation © The Go Authors, giấy phép CC BY 3.0. Bản dịch và ghi chú: Lê Văn Dũng.