国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

? ??? ?? Golang Go ???????? ??, ??, ?? ?? ??

Go ???????? ??, ??, ?? ?? ??

Nov 21, 2024 am 09:21 AM

Improving Request, Validation, and Response Handling in Go Microservices

? ?????? ???, ???? ? ?? ??? ??? ?????? ??? Go ????????? ??, ?? ? ?? ??? ???? ??? ?????.

??

?? ? ???? Go?? ??????? ??? ??? ? ??? ???? ???? ???? ?? ???? ????. ?? Go?? ?? ???? ? ? ??? ???? ?? ?? ???? ???? ????. ??? ?? ???? ?? ?????.

??? ??? ?? ??? ??? ??? ? ???, ?? API ?????? ??? ???? ????? ?? ?? ?????. ?? ? ??? ???? ?? ??? ?? ??? ????? ?? Go ??? ???? ?? ?? ??? ?? ????? ??? ????. ? ????? ? ????? "??"? ?? ??? ???? ??? ?????. ? ???? ???? ??? ??? ??, ??? ? ?? ?? ?? ??? ?? ?? ??? ?? ???? ? ?? ?? ??? API? ?? ??? ? ??? ??? ? ?????. ?? ?? ???? ???? ?? ???? ??? ??? ? ??? ??? ?????.

??

Go ???????? ??? ? ???? ?? ? ??? ???? HTTP ??? ????? ???? ????. ? ?????? ????? ?? ?? ?? ??, ???? ??, ??? ??? ?? ? ??? ?? ??? ?????. ?? ?? ??? ???????.

package main

import (
 "encoding/json"
 "github.com/go-chi/chi/v5"
 "github.com/go-chi/chi/v5/middleware"
 "github.com/go-playground/validator/v10"
 "log"
 "net/http"
)

type SampleRequest struct {
 Name string `json:"name" validate:"required,min=3"`
 Age  int    `json:"age" validate:"required,min=1"`
}

var validate = validator.New()

type ValidationErrors struct {
 Errors map[string][]string `json:"errors"`
}

func main() {
 r := chi.NewRouter()
 r.Use(middleware.Logger)
 r.Use(middleware.Recoverer)

 r.Post("/submit/{name}", func(w http.ResponseWriter, r *http.Request) {
  sampleReq := &SampleRequest{}

  // Set the path parameter
  name := chi.URLParam(r, "name")
  if name == "" {
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
    "code":    http.StatusBadRequest,
    "message": "name is required",
   })
   return
  }
  sampleReq.Name = name

  // Parse and decode the JSON body
  if err := json.NewDecoder(r.Body).Decode(sampleReq); err != nil {
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
    "code":    http.StatusBadRequest,
    "message": "Invalid JSON format",
   })
   return
  }

  // Validate the request
  if err := validate.Struct(sampleReq); err != nil {
   validationErrors := make(map[string][]string)
   for _, err := range err.(validator.ValidationErrors) {
    fieldName := err.Field()
    validationErrors[fieldName] = append(validationErrors[fieldName], err.Tag())
   }
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
    "code":    http.StatusBadRequest,
    "message": "Validation error",
    "body":    ValidationErrors{Errors: validationErrors},
   })
   return
  }

  // Send success response
  w.WriteHeader(http.StatusOK)
  json.NewEncoder(w).Encode(map[string]interface{}{
   "code":    http.StatusOK,
   "message": "Request received successfully",
   "body":    sampleReq,
  })
 })

 log.Println("Starting server on :8080")
 http.ListenAndServe(":8080", r)
}

???? ???? ??? ??? ???? ?? ??? ???????.

  • ?? ???? ??: ?? ?? ????? ??? ???? ?????.
  • ?? ?? ???: ?? JSON? ???? ?? ????? ??
  • ??: ??? ??? ???? ???? ?? ??? ?? ?? ??? ????? ?????.
  • ?? ??: ??? ??? ????? JSON ??? ??? ?? ??? ?? ???? ?????? ?????.
  • ??? ??: ???? ?? ??? ?????.

??? ?????? ??? ??? ?????? ?? ????? ?? ??? ?? ??? ??? ????? ?? ??? ? ??? ???? ???? ????.

?? ??? ??? ? ?????

?? ??

? ??? ???? ?? ?? ???? ????? ?? ??? ??, ??, ????? ? ?? ???? ???? ??????. ? ?? ??? ? ??? ??? ????? ???? ???? ????? ?????? ? ????.

?? ???

?? ???? ???? HTTP ???? ???? ?? ???? ???? ??? ?????. ? ??? ?????? ??? ?? ??? ????? ?? ?? ??? ???? ????? ? ? ????.

?? ???

?? ???? ?? ??? ??? ?? ?? ??? ???? ???? ?? ??? ???. ??? ?? ??? ?? ??? ?? ??? ??? ????? ??? ??????? ?? ?? ? ???? ?? ??????.

?? ??

?? ???? ??? ??? ??? ?????. ?? ??? ?? ??????? ?? API ??? ??? ??? ???? ???? ???? ????? ????? ?? ??? ??? ? ????.

???… ??? ???? ???? ????, ????, ?????? ?? ??? ??? ? ?? ???? ????. ???? ???? ??? ???? ???? ??? ????? ? ???? ? ???, ??? ?????? ?? ??? ???? ???? ?? ????? ??? ? ??? ????? ??? ??????? ??? ? ????. ??? ???? ???? ? ??? ????? ??? ??? ???? ? ??? ???.

???? ?? ??? ?? ???? ?? ????? ?? ????. ???? ?? ?? ??? ?? ?? ??? ??? ??? ??? ??? ?????.

??? ???? ????

1??: ?? ?? ??

?? ??? ?????? ?? ?? ??? ?? ??? ??? ??????. ? ???? ?? ??? ?? ?? ???? ??? ??? ?? ???? ?? ??? ????? ???.

? ?? ??? httpsuite/request.go:

package main

import (
 "encoding/json"
 "github.com/go-chi/chi/v5"
 "github.com/go-chi/chi/v5/middleware"
 "github.com/go-playground/validator/v10"
 "log"
 "net/http"
)

type SampleRequest struct {
 Name string `json:"name" validate:"required,min=3"`
 Age  int    `json:"age" validate:"required,min=1"`
}

var validate = validator.New()

type ValidationErrors struct {
 Errors map[string][]string `json:"errors"`
}

func main() {
 r := chi.NewRouter()
 r.Use(middleware.Logger)
 r.Use(middleware.Recoverer)

 r.Post("/submit/{name}", func(w http.ResponseWriter, r *http.Request) {
  sampleReq := &SampleRequest{}

  // Set the path parameter
  name := chi.URLParam(r, "name")
  if name == "" {
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
    "code":    http.StatusBadRequest,
    "message": "name is required",
   })
   return
  }
  sampleReq.Name = name

  // Parse and decode the JSON body
  if err := json.NewDecoder(r.Body).Decode(sampleReq); err != nil {
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
    "code":    http.StatusBadRequest,
    "message": "Invalid JSON format",
   })
   return
  }

  // Validate the request
  if err := validate.Struct(sampleReq); err != nil {
   validationErrors := make(map[string][]string)
   for _, err := range err.(validator.ValidationErrors) {
    fieldName := err.Field()
    validationErrors[fieldName] = append(validationErrors[fieldName], err.Tag())
   }
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
    "code":    http.StatusBadRequest,
    "message": "Validation error",
    "body":    ValidationErrors{Errors: validationErrors},
   })
   return
  }

  // Send success response
  w.WriteHeader(http.StatusOK)
  json.NewEncoder(w).Encode(map[string]interface{}{
   "code":    http.StatusOK,
   "message": "Request received successfully",
   "body":    sampleReq,
  })
 })

 log.Println("Starting server on :8080")
 http.ListenAndServe(":8080", r)
}

??: ? ????? ????? ???? ????. ??? ?? ? ?? ??? ???? ?? ???? ? ????. ?

?? ?? ???? ?? ???? ??? ?? httpssuite/request_test.go:
? ????.

package httpsuite

import (
 "encoding/json"
 "errors"
 "github.com/go-chi/chi/v5"
 "net/http"
 "reflect"
)

// RequestParamSetter defines the interface used to set the parameters to the HTTP request object by the request parser.
// Implementing this interface allows custom handling of URL parameters.
type RequestParamSetter interface {
 // SetParam assigns a value to a specified field in the request struct.
 // The fieldName parameter is the name of the field, and value is the value to set.
 SetParam(fieldName, value string) error
}

// ParseRequest parses the incoming HTTP request into a specified struct type, handling JSON decoding and URL parameters.
// It validates the parsed request and returns it along with any potential errors.
// The pathParams variadic argument allows specifying URL parameters to be extracted.
// If an error occurs during parsing, validation, or parameter setting, it responds with an appropriate HTTP status.
func ParseRequest[T RequestParamSetter](w http.ResponseWriter, r *http.Request, pathParams ...string) (T, error) {
 var request T
 var empty T

 defer func() {
  _ = r.Body.Close()
 }()

 if r.Body != http.NoBody {
  if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
   SendResponse[any](w, "Invalid JSON format", http.StatusBadRequest, nil)
   return empty, err
  }
 }

 // If body wasn't parsed request may be nil and cause problems ahead
 if isRequestNil(request) {
  request = reflect.New(reflect.TypeOf(request).Elem()).Interface().(T)
 }

 // Parse URL parameters
 for _, key := range pathParams {
  value := chi.URLParam(r, key)
  if value == "" {
   SendResponse[any](w, "Parameter "+key+" not found in request", http.StatusBadRequest, nil)
   return empty, errors.New("missing parameter: " + key)
  }

  if err := request.SetParam(key, value); err != nil {
   SendResponse[any](w, "Failed to set field "+key, http.StatusInternalServerError, nil)
   return empty, err
  }
 }

 // Validate the combined request struct
 if validationErr := IsRequestValid(request); validationErr != nil {
  SendResponse[ValidationErrors](w, "Validation error", http.StatusBadRequest, validationErr)
  return empty, errors.New("validation error")
 }

 return request, nil
}

func isRequestNil(i interface{}) bool {
 return i == nil || (reflect.ValueOf(i).Kind() == reflect.Ptr && reflect.ValueOf(i).IsNil())
}

????? Request ???? Validation ???? ?????. ??? ?? ??? ? ?? ? ?? ??? ??? ?? ???? ???? ???? ?? ?? ?? ??? ???? ???? ??? ??? ???? ????.

??? ?? ???? ?? ???? ???? ?? ?????? ???? ?? ???? ????? ??? ?? ????.

2??: ?? ?? ??

?? ?? ??? ???? ??? ?? ??? ???? ??? ??? ?? ?? ?? ??? ????. ? ??? ?????? ?? ????? ?? ?????? ?? ??? ??? ?? ??? ??? ? ????.

?? ?? httpsuite/validation.go ??? ??? ?????.

package main

import (
 "encoding/json"
 "github.com/go-chi/chi/v5"
 "github.com/go-chi/chi/v5/middleware"
 "github.com/go-playground/validator/v10"
 "log"
 "net/http"
)

type SampleRequest struct {
 Name string `json:"name" validate:"required,min=3"`
 Age  int    `json:"age" validate:"required,min=1"`
}

var validate = validator.New()

type ValidationErrors struct {
 Errors map[string][]string `json:"errors"`
}

func main() {
 r := chi.NewRouter()
 r.Use(middleware.Logger)
 r.Use(middleware.Recoverer)

 r.Post("/submit/{name}", func(w http.ResponseWriter, r *http.Request) {
  sampleReq := &SampleRequest{}

  // Set the path parameter
  name := chi.URLParam(r, "name")
  if name == "" {
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
    "code":    http.StatusBadRequest,
    "message": "name is required",
   })
   return
  }
  sampleReq.Name = name

  // Parse and decode the JSON body
  if err := json.NewDecoder(r.Body).Decode(sampleReq); err != nil {
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
    "code":    http.StatusBadRequest,
    "message": "Invalid JSON format",
   })
   return
  }

  // Validate the request
  if err := validate.Struct(sampleReq); err != nil {
   validationErrors := make(map[string][]string)
   for _, err := range err.(validator.ValidationErrors) {
    fieldName := err.Field()
    validationErrors[fieldName] = append(validationErrors[fieldName], err.Tag())
   }
   w.WriteHeader(http.StatusBadRequest)
   json.NewEncoder(w).Encode(map[string]interface{}{
    "code":    http.StatusBadRequest,
    "message": "Validation error",
    "body":    ValidationErrors{Errors: validationErrors},
   })
   return
  }

  // Send success response
  w.WriteHeader(http.StatusOK)
  json.NewEncoder(w).Encode(map[string]interface{}{
   "code":    http.StatusOK,
   "message": "Request received successfully",
   "body":    sampleReq,
  })
 })

 log.Println("Starting server on :8080")
 http.ListenAndServe(":8080", r)
}

?? ??? ??? ?????. httpsuite/validation_test.go:

package httpsuite

import (
 "encoding/json"
 "errors"
 "github.com/go-chi/chi/v5"
 "net/http"
 "reflect"
)

// RequestParamSetter defines the interface used to set the parameters to the HTTP request object by the request parser.
// Implementing this interface allows custom handling of URL parameters.
type RequestParamSetter interface {
 // SetParam assigns a value to a specified field in the request struct.
 // The fieldName parameter is the name of the field, and value is the value to set.
 SetParam(fieldName, value string) error
}

// ParseRequest parses the incoming HTTP request into a specified struct type, handling JSON decoding and URL parameters.
// It validates the parsed request and returns it along with any potential errors.
// The pathParams variadic argument allows specifying URL parameters to be extracted.
// If an error occurs during parsing, validation, or parameter setting, it responds with an appropriate HTTP status.
func ParseRequest[T RequestParamSetter](w http.ResponseWriter, r *http.Request, pathParams ...string) (T, error) {
 var request T
 var empty T

 defer func() {
  _ = r.Body.Close()
 }()

 if r.Body != http.NoBody {
  if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
   SendResponse[any](w, "Invalid JSON format", http.StatusBadRequest, nil)
   return empty, err
  }
 }

 // If body wasn't parsed request may be nil and cause problems ahead
 if isRequestNil(request) {
  request = reflect.New(reflect.TypeOf(request).Elem()).Interface().(T)
 }

 // Parse URL parameters
 for _, key := range pathParams {
  value := chi.URLParam(r, key)
  if value == "" {
   SendResponse[any](w, "Parameter "+key+" not found in request", http.StatusBadRequest, nil)
   return empty, errors.New("missing parameter: " + key)
  }

  if err := request.SetParam(key, value); err != nil {
   SendResponse[any](w, "Failed to set field "+key, http.StatusInternalServerError, nil)
   return empty, err
  }
 }

 // Validate the combined request struct
 if validationErr := IsRequestValid(request); validationErr != nil {
  SendResponse[ValidationErrors](w, "Validation error", http.StatusBadRequest, validationErr)
  return empty, errors.New("validation error")
 }

 return request, nil
}

func isRequestNil(i interface{}) bool {
 return i == nil || (reflect.ValueOf(i).Kind() == reflect.Ptr && reflect.ValueOf(i).IsNil())
}

3??: ?? ?? ??

????? ?? ??? ??? ??? ???????. ??? ?? ?? ??? ??? ??? ???? ?????? ???? ??? ?? ?? ?????? ???? ? ????.

?? ??? httpsuite/response.go:

package httpsuite

import (
 "bytes"
 "context"
 "encoding/json"
 "errors"
 "fmt"
 "github.com/go-chi/chi/v5"
 "github.com/stretchr/testify/assert"
 "log"
 "net/http"
 "net/http/httptest"
 "strconv"
 "strings"
 "testing"
)

// TestRequest includes custom type annotation for UUID
type TestRequest struct {
 ID   int    `json:"id" validate:"required"`
 Name string `json:"name" validate:"required"`
}

func (r *TestRequest) SetParam(fieldName, value string) error {
 switch strings.ToLower(fieldName) {
 case "id":
  id, err := strconv.Atoi(value)
  if err != nil {
   return errors.New("invalid id")
  }
  r.ID = id
 default:
  log.Printf("Parameter %s cannot be set", fieldName)
 }

 return nil
}

func Test_ParseRequest(t *testing.T) {
 testSetURLParam := func(r *http.Request, fieldName, value string) *http.Request {
  ctx := chi.NewRouteContext()
  ctx.URLParams.Add(fieldName, value)
  return r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx))
 }

 type args struct {
  w          http.ResponseWriter
  r          *http.Request
  pathParams []string
 }
 type testCase[T any] struct {
  name    string
  args    args
  want    *TestRequest
  wantErr assert.ErrorAssertionFunc
 }
 tests := []testCase[TestRequest]{
  {
   name: "Successful Request",
   args: args{
    w: httptest.NewRecorder(),
    r: func() *http.Request {
     body, _ := json.Marshal(TestRequest{Name: "Test"})
     req := httptest.NewRequest("POST", "/test/123", bytes.NewBuffer(body))
     req = testSetURLParam(req, "ID", "123")
     req.Header.Set("Content-Type", "application/json")
     return req
    }(),
    pathParams: []string{"ID"},
   },
   want:    &TestRequest{ID: 123, Name: "Test"},
   wantErr: assert.NoError,
  },
  {
   name: "Missing body",
   args: args{
    w: httptest.NewRecorder(),
    r: func() *http.Request {
     req := httptest.NewRequest("POST", "/test/123", nil)
     req = testSetURLParam(req, "ID", "123")
     req.Header.Set("Content-Type", "application/json")
     return req
    }(),
    pathParams: []string{"ID"},
   },
   want:    nil,
   wantErr: assert.Error,
  },
  {
   name: "Missing Path Parameter",
   args: args{
    w: httptest.NewRecorder(),
    r: func() *http.Request {
     req := httptest.NewRequest("POST", "/test", nil)
     req.Header.Set("Content-Type", "application/json")
     return req
    }(),
    pathParams: []string{"ID"},
   },
   want:    nil,
   wantErr: assert.Error,
  },
  {
   name: "Invalid JSON Body",
   args: args{
    w: httptest.NewRecorder(),
    r: func() *http.Request {
     req := httptest.NewRequest("POST", "/test/123", bytes.NewBufferString("{invalid-json}"))
     req = testSetURLParam(req, "ID", "123")
     req.Header.Set("Content-Type", "application/json")
     return req
    }(),
    pathParams: []string{"ID"},
   },
   want:    nil,
   wantErr: assert.Error,
  },
  {
   name: "Validation Error for body",
   args: args{
    w: httptest.NewRecorder(),
    r: func() *http.Request {
     body, _ := json.Marshal(TestRequest{})
     req := httptest.NewRequest("POST", "/test/123", bytes.NewBuffer(body))
     req = testSetURLParam(req, "ID", "123")
     req.Header.Set("Content-Type", "application/json")
     return req
    }(),
    pathParams: []string{"ID"},
   },
   want:    nil,
   wantErr: assert.Error,
  },
  {
   name: "Validation Error for zero ID",
   args: args{
    w: httptest.NewRecorder(),
    r: func() *http.Request {
     body, _ := json.Marshal(TestRequest{Name: "Test"})
     req := httptest.NewRequest("POST", "/test/0", bytes.NewBuffer(body))
     req = testSetURLParam(req, "ID", "0")
     req.Header.Set("Content-Type", "application/json")
     return req
    }(),
    pathParams: []string{"ID"},
   },
   want:    nil,
   wantErr: assert.Error,
  },
 }

 for _, tt := range tests {
  t.Run(tt.name, func(t *testing.T) {
   got, err := ParseRequest[*TestRequest](tt.args.w, tt.args.r, tt.args.pathParams...)
   if !tt.wantErr(t, err, fmt.Sprintf("parseRequest(%v, %v, %v)", tt.args.w, tt.args.r, tt.args.pathParams)) {
    return
   }
   assert.Equalf(t, tt.want, got, "parseRequest(%v, %v, %v)", tt.args.w, tt.args.r, tt.args.pathParams)
  })
 }
}

??? ?? ??? httpsuite/response_test.go:

package httpsuite

import (
 "errors"
 "github.com/go-playground/validator/v10"
)

// ValidationErrors represents a collection of validation errors for an HTTP request.
type ValidationErrors struct {
 Errors map[string][]string `json:"errors,omitempty"`
}

// NewValidationErrors creates a new ValidationErrors instance from a given error.
// It extracts field-specific validation errors and maps them for structured output.
func NewValidationErrors(err error) *ValidationErrors {
 var validationErrors validator.ValidationErrors
 errors.As(err, &validationErrors)

 fieldErrors := make(map[string][]string)
 for _, vErr := range validationErrors {
  fieldName := vErr.Field()
  fieldError := fieldName + " " + vErr.Tag()

  fieldErrors[fieldName] = append(fieldErrors[fieldName], fieldError)
 }

 return &ValidationErrors{Errors: fieldErrors}
}

// IsRequestValid validates the provided request struct using the go-playground/validator package.
// It returns a ValidationErrors instance if validation fails, or nil if the request is valid.
func IsRequestValid(request any) *ValidationErrors {
 validate := validator.New(validator.WithRequiredStructEnabled())
 err := validate.Struct(request)
 if err != nil {
  return NewValidationErrors(err)
 }
 return nil
}

? ????? ? ??? ?? ? ??? ???? ?? ??? ???? ??? ??? ???? ? ????. ?? ???? ?? ??? ????? ??? ??? ???? ?? ??, ??? ?? ? ?? ??? ?? ???? ??? ???? ??? ?????.

?? ?? ????

?? ??? ?? ???? ????? ?? ??? ???? ??? ???? ???? ????.

package httpsuite

import (
 "github.com/go-playground/validator/v10"
 "testing"

 "github.com/stretchr/testify/assert"
)

type TestValidationRequest struct {
 Name string `validate:"required"`
 Age  int    `validate:"required,min=18"`
}

func TestNewValidationErrors(t *testing.T) {
 validate := validator.New()
 request := TestValidationRequest{} // Missing required fields to trigger validation errors

 err := validate.Struct(request)
 if err == nil {
  t.Fatal("Expected validation errors, but got none")
 }

 validationErrors := NewValidationErrors(err)

 expectedErrors := map[string][]string{
  "Name": {"Name required"},
  "Age":  {"Age required"},
 }

 assert.Equal(t, expectedErrors, validationErrors.Errors)
}

func TestIsRequestValid(t *testing.T) {
 tests := []struct {
  name           string
  request        TestValidationRequest
  expectedErrors *ValidationErrors
 }{
  {
   name:           "Valid request",
   request:        TestValidationRequest{Name: "Alice", Age: 25},
   expectedErrors: nil, // No errors expected for valid input
  },
  {
   name:    "Missing Name and Age below minimum",
   request: TestValidationRequest{Age: 17},
   expectedErrors: &ValidationErrors{
    Errors: map[string][]string{
     "Name": {"Name required"},
     "Age":  {"Age min"},
    },
   },
  },
  {
   name:    "Missing Age",
   request: TestValidationRequest{Name: "Alice"},
   expectedErrors: &ValidationErrors{
    Errors: map[string][]string{
     "Age": {"Age required"},
    },
   },
  },
 }

 for _, tt := range tests {
  t.Run(tt.name, func(t *testing.T) {
   errs := IsRequestValid(tt.request)
   if tt.expectedErrors == nil {
    assert.Nil(t, errs)
   } else {
    assert.NotNil(t, errs)
    assert.Equal(t, tt.expectedErrors.Errors, errs.Errors)
   }
  })
 }
}

?? ?? ??, ??? ?? ? ?? ?? ??? ?? ??? ??? ???? ???????? ??? ??? ??? ????? ???? ??? ????? ??????. ? ??? ?? ??? ???? ???? ?? ??? ? ??? ???? ??? ???? ?? ?? ?? ???? ??? ???? ??????. ?? ???? ????? ?? ???? ?? ??? ??? ?? ?? ?? ???? ?? ???? ??? ? ?? ? ???? ???? ??? ?????? ?? ? ????.

??

?? ??, ?? ? ?? ???? ???? Go ???????? ???? ??? ?? ? ??? ???? ? ???? ?? ???? ?? ??? ??? ? ??? ??? ????. ? ?? ??? ?? ??? ??? ?? ????. ?? ?? ??? ?? ??? ?? ???? ??? ?????? ? ????? ??? ????? ?????????

?? ??? ???? ?????? ?? httpssuite? ???? ?? ????. rluders/httpsuite ????? ?????? ?? ? ????. ???? ???? ??? ? ?????? Go ?????? ?? ???? ???? ??? ? ?? ??? ????.

????? ?????.

? ??? Go ???????? ??, ??, ?? ?? ??? ?? ?????. ??? ??? PHP ??? ????? ?? ?? ??? ?????!

? ????? ??
? ?? ??? ????? ???? ??? ??????, ???? ?????? ????. ? ???? ?? ???? ?? ??? ?? ????. ???? ??? ???? ???? ??? ?? admin@php.cn?? ?????.

? AI ??

Undresser.AI Undress

Undresser.AI Undress

???? ?? ??? ??? ?? AI ?? ?

AI Clothes Remover

AI Clothes Remover

???? ?? ???? ??? AI ?????.

Video Face Swap

Video Face Swap

??? ??? AI ?? ?? ??? ???? ?? ???? ??? ?? ????!

???

??? ??

???++7.3.1

???++7.3.1

???? ?? ?? ?? ???

SublimeText3 ??? ??

SublimeText3 ??? ??

??? ??, ???? ?? ????.

???? 13.0.1 ???

???? 13.0.1 ???

??? PHP ?? ?? ??

???? CS6

???? CS6

??? ? ?? ??

SublimeText3 Mac ??

SublimeText3 Mac ??

? ??? ?? ?? ?????(SublimeText3)

???

??? ??

?? ????
1783
16
Cakephp ????
1728
56
??? ????
1577
28
PHP ????
1442
31
???
????? GO? ?? ??? ??? ?????? ????? GO? ?? ??? ??? ?????? Jun 19, 2025 am 01:08 AM

GO? ????? ????? ??? ????? ??????. ?? ??? ?? ?????. 1. ? ??? ?? : Linux ????? ?? ??? ?????? ??? ??? ? ????. 2. ?? ??? ??? ?? ???? ???? ?? ??? ????? ?? ??? ?? ?? ??? ?? ??? ? ? ????. 3. ?? ?? ???? ?? : ?? ????? ??? ??? ?? ??? ??? ???? ??????. 4. ??? ?? ??? : ??? ???? ????? ?? ?????? ? ???? ? ? ??? ??? ? ??? ?????. ??? ??? CLI ??, ???? ??? ? ?? ????? ????? ????? ????? ?? ??? ??? ???? ????? ???? ??? ?????.

GO? C? ?? ?? ??? ???? ??? ??? ??? ?????? GO? C? ?? ?? ??? ???? ??? ??? ??? ?????? Jun 19, 2025 am 01:11 AM

goensuresmemorysafety? ?? MemolemanucameThrougatomaticgargarbagecollection, nopointerarithmetic, safeconcurrency, andruntimechecks.first, go'sgarbagecollectoricallyally reclaimsunusedmemory, ??, itdisallowspointe, itdisallowspointe ??

Go?? ??? ? ??? ??? ?????? (? : Make (Chan Int, 10)) Go?? ??? ? ??? ??? ?????? (? : Make (Chan Int, 10)) Jun 20, 2025 am 01:07 AM

GO?? ?? ??? ???? MAKE ??? ?? ?? ?? ? ??????. ?? ??? ???? ??? ??? ???? ?? ? ???? ?? ? ?? ??? ???? ?? ? ???? ??? ??? ? ????. ?? ??, ch : = make (Chanint, 10)? ?? 10 ?? ?? ?? ??? ??? ?? ??? ????. ???? ?? ??? ??, ??? ???? ?? ???? ??? ???? ???? ?? ? ??? ??? ????? ?????. ??? ??? ?, ?? : 1. ?? ??? ??? ??? ?? ??? ??? ??? ?? ?????????. 2. ??? ??? ??? ??? ??? ???? ?? ???????. 3. ??? chanstruct {} ??? ?? ?? ? ? ????. ???? ?????? ??? ?, ??? ??? ?? ? ???? ?????.

??? ????? ??? GO? ??? ??? ? ????? ??? ????? ??? GO? ??? ??? ? ????? Jun 19, 2025 am 01:10 AM

GO? ??? ?????? ??????. C? ?? ??? ? ??? ??? ?? ??? ?? ??? ? ??? ???? ?? ?????. 1. ?? ? ???? ?? ???? Go? OS ???? ?? ? ????? ????? ??? ??, ??, ?? ??? ? ???? ?? ?????. OS.ReadFile? ???? ? ?? ??? ?? ??? ?????. ?? ???? ?? ?? ?? ??? ???? ? ?????. 2. ???? ?? ???? OS/EXEC ???? exec.command ??? ?? ??? ????, ??? ????, ?? ??? ????, ?? ? ?? ??? ?????? ?? ??, ??? ?? ? ?? ????? ??? ???? ????? ?? ? ? ????. 3. ???? ? ??? ???? Net ???? TCP/UDP ?????, DNS ?? ? ?? ??? ?????.

Go? ??? ?????? ???? ????? ????????? Go? ??? ?????? ???? ????? ????????? Jun 24, 2025 pm 03:17 PM

GO ???? ?? ??? ????? ?? ???? ????? ?? ? ???? ???? ??? ??? ???? ????????. ?? ???? ??? ?, ???? ? ??? ?? ??? ???? ?? ?? ? ? ????. 1. func (rrectangle) area () int? ?? ? ???? ???? rect.area ()? ?? ?? ??????. 2. ??? ?? ???? ?? func (r*???) setwidth (...)? ?? ??? ???? ???? ???? ?? ??? ???? ?????. 3. ??? ?? ? ?, ?? ??? ??? ?? ? ???, ?? ??? ?? ?? ?? ? ???. 4. Go? Getter/Setter? ??? ???? ??????.

???? ?????? ???? ??? ?????? ???? ?????? ???? ??? ?????? Jun 22, 2025 pm 03:41 PM

GO?? ?????? ??? ???? ?? ??? ???? ?????. ?????? ??? ???? ???? ??? ??? ???? ?? ??? ?????? ???? ??????. ?? ??, speak () ???? ?? ? ??? ?????? ???? ???? ???? ?? ??? ???? ?? ? ? ????. ?????? ???? ??, ?? ?? ?? ?? ? ????? ?? ????? ???? ? ?????. ?????? ???? ????? ???? ???? ??? ??? ???? ??? ?? ??? ???? ?? ?????? ?????. ???? ?? ???? ??, ??, ?? ?????? ?? ???? ??? ? ?? ???? ?????. ?? ??, ?? ?? ??? ?? ??? ??? ???? ??? Anno? ??? ? ????.

Go? ??? ????? ??? ??? ??? ?????? (? :, len (), strings.contains (), strings.index (), strings.replaceall ()) Go? ??? ????? ??? ??? ??? ?????? (? :, len (), strings.contains (), strings.index (), strings.replaceall ()) Jun 20, 2025 am 01:06 AM

Go Language?? ??? ??? ?? ??? ??? ? ?? ??? ?? ?????. 1.Strings.contains ()? ???? ?? ???? ???? ??? ??? ???? ?? ?? ???? ? ?????. 2.strings.index ()? ???? ?? ???? ???? ??? ?? ? ??? ???? ??? -1? ?????. 3.strings.replaceall ()? ?? ???? ?? ??? ?? ? ? ??? Strings.replace ()? ?? ?? ?? ?? ? ? ????. 4.Len () ??? ???? ??? ??? ?? ? ????? ?? ??? ?? ? ?? ??? ???? ?????? ???????. ??? ??? ?? ??? ???, ??? ?? ?? ? ??? ??? ?? ?????? ?????.

IO ???? ???? GO?? ?? ? ?? ???? ?? ???? ??? ?????? IO ???? ???? GO?? ?? ? ?? ???? ?? ???? ??? ?????? Jun 20, 2025 am 11:25 AM

TheGoiopackageprovidesinterfaceslikeReaderandWritertohandleI/Ooperationsuniformlyacrosssources.1.io.Reader'sReadmethodenablesreadingfromvarioussourcessuchasfilesorHTTPresponses.2.io.Writer'sWritemethodfacilitateswritingtodestinationslikestandardoutpu

See all articles