作者 kfrico 的所有文章

Sublime Text PHP開發設定檔

安裝intelephense lsp server

npm install -g intelephense

sublimetext 安裝套件 LSP-intelephens

LSP-intelephense 設定

{
    "schemes": ["file", "buffer"],
    "auto_complete_selector": "punctuation.accessor | punctuation.definition.variable | punctuation.separator.namespace | punctuation.definition.tag.begin",
    "initializationOptions": {
        "clearCache": false,
        // "storagePath": "${temp_dir}/intelephense",
        // "globalStoragePath": "${home}/.intelephense",

        // if you want to use a premium license, you can either paste the key directly
        // or paste it into a file and provide its absolute path here
        // "licenceKey": "${packages}/User/intelephense-license.txt",
    },
    // @see configuration in https://github.com/bmewburn/vscode-intelephense/blob/master/package.json
    "settings": {
        // There are quite a lot of settings for intelephense...
        // For a full list, you can check the link above or just use LSP-json for autocompletion.

        // Enable a code lens that shows an abstract and interface implementations count and command to peek locations.
        "intelephense.codeLens.implementations.enable": false,

        // Enable a code lens that shows method override count and command to peek locations.
        "intelephense.codeLens.overrides.enable": false,

        // Enable a code lens that indicates if a method has a parent implementation and command to peek location.
        "intelephense.codeLens.parent.enable": false,

        // Enable a code lens that shows a reference count and command to peek locations.
        "intelephense.codeLens.references.enable": false,

        // Enable a code lens that shows a trait usages count and command to peek locations.
        "intelephense.codeLens.usages.enable": false,

        // Resolves `ArrayAccess` and `Traversable` implementations that are unioned with a typed array to generic syntax. eg `ArrayAccessOrTraversable|ElementType[]` => `ArrayAccessOrTraversable<mixed, ElementType>`.
        "intelephense.compatibility.correctForArrayAccessArrayAndTraversableArrayUnionTypes": true,

        // Resolves `BaseClass|static` union types to `static` instead of `BaseClass`.
        "intelephense.compatibility.correctForBaseClassStaticUnionTypes": true,

        // Prefer `@psalm-` and `@phpstan-` prefixed `@return`, `@var`, `@param` tags when determining symbol types.
        "intelephense.compatibility.preferPsalmPhpstanPrefixedAnnotations": false,

        // Global namespace constants and functions will be fully qualified (prefixed with a backslash).
        "intelephense.completion.fullyQualifyGlobalConstantsAndFunctions": false,

        // Use declarations will be automatically inserted for namespaced classes, traits, interfaces, functions, and constants.
        "intelephense.completion.insertUseDeclaration": true,

        // The maximum number of completion items returned per request.
        "intelephense.completion.maxItems": 100,

        // PHP permits the calling of static methods using the object operator eg `$obj->myStaticMethod();`. If you would prefer not to have static methods suggested in this context then set this value to `false`. Defaults to `true`.
        "intelephense.completion.suggestObjectOperatorStaticMethods": true,

        // Method and function completions will include parentheses and trigger parameter hints.
        "intelephense.completion.triggerParameterHints": true,

        // Enables argument count diagnostics.
        "intelephense.diagnostics.argumentCount": true,

        // Enables deprecated diagnostics.
        "intelephense.diagnostics.deprecated": true,

        // Enables duplicate symbol diagnostics.
        "intelephense.diagnostics.duplicateSymbols": true,

        // Enables diagnostics in embedded languages.
        "intelephense.diagnostics.embeddedLanguages": true,

        // Enables diagnostics.
        "intelephense.diagnostics.enable": true,

        // Enables reporting of problems associated with method and class implementations. For example, unimplemented methods or method signature incompatibilities.
        "intelephense.diagnostics.implementationErrors": true,

        // Enables reporting of various language constraint errors.
        "intelephense.diagnostics.languageConstraints": true,

        // This setting turns off type checking for the `mixed` type. This is useful for projects that may have incomplete or innacurate typings. Set to `false` to make type checking more thorough by not allowing `mixed` to satisy any type constraint. This setting has no effect when `relaxedTypeCheck` is `true`.
        "intelephense.diagnostics.noMixedTypeCheck": true,

        // This setting makes type checking less thorough by allowing contravariant (wider) types to also satisfy a type constraint. This is useful for projects that may have incomplete or innacurate typings. Set to `false` for more thorough type checks. When this setting is `true`, the `noMixedTypeCheck` setting is ignored.
        "intelephense.diagnostics.relaxedTypeCheck": true,

        // Controls when diagnostics are run.
        //  - onType: Diagnostics will run as changes are made to the document.
        //  - onSave: Diagnostics will run when the document is saved.
        "intelephense.diagnostics.run": "onType",

        // Enables diagnostics on type compatibility of arguments, property assignments, and return statements where types have been declared.
        "intelephense.diagnostics.typeErrors": true,

        // Enables undefined class constant diagnostics.
        "intelephense.diagnostics.undefinedClassConstants": true,

        // Enables undefined constant diagnostics.
        "intelephense.diagnostics.undefinedConstants": true,

        // Enables undefined function diagnostics.
        "intelephense.diagnostics.undefinedFunctions": true,

        // Enables undefined method diagnostics.
        "intelephense.diagnostics.undefinedMethods": true,

        // Enables undefined property diagnostics.
        "intelephense.diagnostics.undefinedProperties": true,

        // DEPRECATED. Use the setting for each symbol category.
        "intelephense.diagnostics.undefinedSymbols": true,

        // Enables undefined class, interface and trait diagnostics.
        "intelephense.diagnostics.undefinedTypes": true,

        // Enables undefined variable diagnostics.
        "intelephense.diagnostics.undefinedVariables": true,

        // Enables unexpected token diagnostics.
        "intelephense.diagnostics.unexpectedTokens": true,

        // Enables unused variable, private member, and import diagnostics.
        "intelephense.diagnostics.unusedSymbols": true,

        // The directory of the entry point to the application (directory of index.php). Can be absolute or relative to the workspace folder. Used for resolving script inclusion and path suggestions.
        "intelephense.environment.documentRoot": "",

        // The include paths (as individual path items) as defined in the include_path ini setting or paths to external libraries. Can be absolute or relative to the workspace folder. Used for resolving script inclusion and/or adding external symbols to folder.
        "intelephense.environment.includePaths": [],

        // A semver compatible string that represents the target PHP version. Used for providing version appropriate suggestions and diagnostics. PHP 5.3.0 and greater supported.
        "intelephense.environment.phpVersion": "8.3.0",

        // When enabled '<?' will be parsed as a PHP open tag. Defaults to true.
        "intelephense.environment.shortOpenTag": true,

        // Configure glob patterns to make files available for language server features. Inherits from files.associations.
        "intelephense.files.associations": [
            "*.php",
            "*.phtml"
        ],

        // Configure glob patterns to exclude certain files and folders from all language server features. Inherits from files.exclude.
        "intelephense.files.exclude": [
            "**/.git/**",
            "**/.svn/**",
            "**/.hg/**",
            "**/CVS/**",
            "**/.DS_Store/**",
            "**/node_modules/**",
            "**/bower_components/**",
            "**/vendor/**/{Tests,tests}/**",
            "**/.history/**",
            "**/vendor/**/vendor/**"
        ],

        // Maximum file size in bytes.
        "intelephense.files.maxSize": 1000000,

        // Controls formatting style of braces
        //  - per: PHP-FIG PER-CS style. A mix of Allman and K&R. https://www.php-fig.org/per/coding-style/
        //  - allman: Allman. Opening brace on the next line.
        //  - k&r: K&R (1TBS). Opening brace on the same line.
        "intelephense.format.braces": "per",

        // Enables formatting.
        "intelephense.format.enable": true,

        // DEPRECATED. Don't use this. Go to command palette and search for enter licence key.
        "intelephense.licenceKey": "",

        // Maximum memory (in MB) that the server should use. On some systems this may only have effect when runtime has been set. Minimum 256.
        "intelephense.maxMemory": 0,

        // An object that describes the format of generated class/interface/trait phpdoc. The following snippet variables are available: SYMBOL_NAME; SYMBOL_KIND; SYMBOL_TYPE; SYMBOL_NAMESPACE.
        "intelephense.phpdoc.classTemplate": {
            "summary": "$1",
            "tags": [
                "@package ${1:$SYMBOL_NAMESPACE}"
            ]
        },

        // An object that describes the format of generated function/method phpdoc. The following snippet variables are available: SYMBOL_NAME; SYMBOL_KIND; SYMBOL_TYPE; SYMBOL_NAMESPACE.
        "intelephense.phpdoc.functionTemplate": {
            "summary": "$1",
            "tags": [
                "@param ${1:$SYMBOL_TYPE} $SYMBOL_NAME $2",
                "@return ${1:$SYMBOL_TYPE} $2",
                "@throws ${1:$SYMBOL_TYPE} $2"
            ]
        },

        // An object that describes the format of generated property phpdoc. The following snippet variables are available: SYMBOL_NAME; SYMBOL_KIND; SYMBOL_TYPE; SYMBOL_NAMESPACE.
        "intelephense.phpdoc.propertyTemplate": {
            "summary": "$1",
            "tags": [
                "@var ${1:$SYMBOL_TYPE}"
            ]
        },

        // Adds `@return void` to auto generated phpdoc for definitions that do not return a value.
        "intelephense.phpdoc.returnVoid": true,

        // 
        //  - snippet: Auto generated phpdoc is returned in snippet format. Templates are partially resolved by evaluating phpdoc specific variables only.
        //  - text: Auto generated phpdoc is returned as plain text. Templates are resolved completely by the server.
        "intelephense.phpdoc.textFormat": "snippet",

        // Fully qualified names will be used for types when true. When false short type names will be used and imported where appropriate. Overrides intelephense.completion.insertUseDeclaration.
        "intelephense.phpdoc.useFullyQualifiedNames": false,

        // Glob patterns matching files and folders that should be excluded from references search.
        "intelephense.references.exclude": [
            "**/vendor/**"
        ],

        // Glob patterns matching files and folders that should be excluded when renaming symbols. Rename operation will fail if the symbol definition is found in the excluded files/folders.
        "intelephense.rename.exclude": [
            "**/vendor/**"
        ],

        // Controls the scope of a namespace rename operation.
        //  - single: Only symbols defined in the current file are affected. For example, this makes a rename of a namespace the equivalent of a single move class operation.
        //  - all: All symbols that share this namespace, not necessarily defined in the current file will be affected. For example it would move all classes that share this namespace to the new namespace.
        "intelephense.rename.namespaceMode": "single",

        // Path to a Node.js executable. Use this if you wish to use a different version of Node.js. Defaults to Node.js shipped with VSCode.
        "intelephense.runtime": "",

        // Configure stub files for built in symbols and common extensions. The default setting includes PHP core and all bundled extensions.
        "intelephense.stubs": [
            "apache",
            "bcmath",
            "bz2",
            "calendar",
            "com_dotnet",
            "Core",
            "ctype",
            "curl",
            "date",
            "dba",
            "dom",
            "enchant",
            "exif",
            "FFI",
            "fileinfo",
            "filter",
            "fpm",
            "ftp",
            "gd",
            "gettext",
            "gmp",
            "hash",
            "iconv",
            "imap",
            "intl",
            "json",
            "ldap",
            "libxml",
            "mbstring",
            "meta",
            "mysqli",
            "oci8",
            "odbc",
            "openssl",
            "pcntl",
            "pcre",
            "PDO",
            "pdo_ibm",
            "pdo_mysql",
            "pdo_pgsql",
            "pdo_sqlite",
            "pgsql",
            "Phar",
            "posix",
            "pspell",
            "random",
            "readline",
            "Reflection",
            "session",
            "shmop",
            "SimpleXML",
            "snmp",
            "soap",
            "sockets",
            "sodium",
            "SPL",
            "sqlite3",
            "standard",
            "superglobals",
            "sysvmsg",
            "sysvsem",
            "sysvshm",
            "tidy",
            "tokenizer",
            "xml",
            "xmlreader",
            "xmlrpc",
            "xmlwriter",
            "xsl",
            "Zend OPcache",
            "zip",
            "zlib"
        ],

        // Anonymous usage and crash data will be sent to Azure Application Insights. Inherits from telemetry.enableTelemetry.
        "intelephense.telemetry.enabled": null,

        // Traces the communication between VSCode and the intelephense language server.
        "intelephense.trace.server": "off",
        "statusText": "{% if server_version %}v{{ server_version }}{% endif %}",
    },
    "selector": "embedding.php",
    "priority_selector": "source.php",
}

Sublime Text 開發設定檔

{
	"auto_complete": true,
	"auto_match_enabled": true,
	"auto_upgrade_ignore":
	[
		"GoSublime"
	],
	"autocomplete_suggest_imports": true,
	"color_scheme": "Packages/Monokai Extended/Monokai Extended Origin.tmTheme",
	"env":
	{
		"GOPATH": "/Users/ken_jan/go",
		"GOROOT": "/usr/local/go",
	},
	"file_exclude_patterns":
	[
		"*.odp",
		"*.pptx",
		"*.docx",
		"*.xlsx",
		"*.pdf",
		"*.cache",
		"*.pyc",
		"*.pyo",
		"*.exe",
		"*.dll",
		"*.obj",
		"*.o",
		"*.a",
		"*.lib",
		"*.so",
		"*.dylib",
		"*.ncb",
		"*.sdf",
		"*.suo",
		"*.pdb",
		"*.idb",
		".DS_Store",
		"*.class",
		"*.psd",
		"*.db"
	],
	"folder_exclude_patterns":
	[
		".svn",
		".git",
		".hg",
		"CVS",
		".tdlib"
	],
	"font_face": "Menlo, Monaco, 'Courier New', monospace",
	"font_options":
	[
	],
	"font_size": 12,
	"highlight_line": true,
	"highlight_modified_tabs": true,
	"ignored_packages":
	[
		"SublimeLinter",
		"Vintage",
	],
	"index_exclude_patterns":
	[
		"*.odp",
		"*.pptx",
		"*.docx",
		"*.xlsx",
		"*.pdf",
		"*.cache",
		"*.pyc",
		"*.pyo",
		"*.exe",
		"*.dll",
		"*.obj",
		"*.o",
		"*.a",
		"*.lib",
		"*.so",
		"*.dylib",
		"*.ncb",
		"*.sdf",
		"*.suo",
		"*.pdb",
		"*.idb",
		".DS_Store",
		"*.class",
		"*.psd",
		"*.db",
		"*.sublime-workspace"
	],
	"mini_diff": false,
	"monokai_pro_small_scrollbar": true,
	"show_full_path": true,
	"show_git_status": false,
	"theme": "Monokai Classic.sublime-theme",
	"theme_font_options":
	[
	],
	"translate_tabs_to_spaces": true,
	"wide_caret": true,
	"word_separators": "./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}`~?:",
}

Go http 的幾種錯誤

之前遇到了很多 timeout,但是仔細看錯誤提示好像不完全一樣,於是就做了個簡單的試驗:

Client 上看到的錯誤

找不到服務器(no such host)的幾種情況:

# 域名不存在,瞄了下代碼,應該是 dns 包返回的
Get http://a.b/abc: dial tcp: lookup a.b: no such host

# ip 不合法不會直接檢查,也會返回同樣錯誤
Get http://127.0.0.1888:8080/abc: dial tcp: lookup 127.0.0.1888: no such host

# 端口瞎填會直接報錯,都不會發請求
Get http://127.0.0.1:65536/abc: dial tcp: address 65536: invalid port


拒絕連接,對方端口未監聽、進程掛掉等等

Get http://127.0.0.1:8080/abc: dial tcp 127.0.0.1:8080: connect: connection refused


建立連接超時

Get http://127.0.0:8080/abc: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)


等待返回 header, 一般是接口還在處理邏輯,沒有返回任何數據;或者對方只是個普通的 tcp 服務,但不是 http

Get http://127.0.0.1:8080/abc: net/http: request canceled (Client.Timeout exceeded while awaiting headers)


客戶端讀取超時:已建立好連接,已經開始返回數據,但是body 太大太慢:

wait_test.go:48: net/http: request canceled (Client.Timeout exceeded while reading body)


Server 上看到的錯誤

客戶端主動斷開連接,服務器端在調用 Write(p []byte) (n int, err error) 時會返回:

wait_test.go:21: write tcp 127.0.0.1:8080->127.0.0.1:49290: write: broken pipe


客戶端主動斷開連接,通常會直接使用 ctx.Done() 檢測到,這個時候 ctx.Err() 裡會拿到這個信息:

context canceled

參考連結

https://romatic.net/post/go_net_errors/

https://colobu.com/2016/07/01/the-complete-guide-to-golang-net-http-timeouts/

Sublime Text 開發 Golang 環境配置

Sublime Text Package 安裝

GoSublime

在margo.go 註解改用LSP gopls
 
 // &golang.Gocode{
 // // Whether or not to do gocode completion using source code
 // // instead of the pre-compiled package files.
 // // Using source is often slower but offer more up-to-date completions.
 // Source: true,

 // // show the function parameters. this can take up a lot of space
 // ShowFuncParams: true,

 // // whether or not to include Test*, Benchmark* and Example* functions in the auto-completion list
 // // gs: this replaces the `autocomplete_tests` setting
 // ProposeTests: false,

 // // whether or not builtin types and functions should be shown in the auto-completion list
 // // gs: this replaces the `autocomplete_builtins` setting
 // ProposeBuiltins: true,
 // },


 golangci-lint 啟用這些檢查

 &golang.Linter{Name: "golangci-lint", Args: []string{
 "run",

 // 2019/10/29增加
 "--enable=interfacer",
 "--enable=nakedret",
 "--enable=goconst",

 "--enable=bodyclose",
 "--enable=gocritic",
 "--enable=prealloc",
 "--enable=unconvert",
 "--enable=whitespace",
 "--enable=wsl",

 "--disable=deadcode",
 "--max-same-issues=0",
 "--fast",
 }},
LSP (gopls)

配置設定
{
    "auto_show_diagnostics_panel": "never",
    "show_diagnostics_in_view_status": false,
    "log_server": false,
	"clients":
	{
		"gopls":
		{
			"enabled": true
		}
	}
}

還需要特別安裝
LSP-gopls套件

=============2024/05/29更新======================
Gosublime停止更新,不支援sublime text 4
只需要安裝LSP套件

// Settings in here override those in "LSP/LSP.sublime-settings"
{
    "show_diagnostics_in_view_status": false,
    "clients":
    {
        "gopls":
        {
            "enabled": true
        }
    },
    "lsp_format_on_save": true,
    "lsp_code_actions_on_save": {
        "source.fixAll": false, // 自動修復所有錯誤
        "source.organizeImports": true // 自動新增排序import套件
    }
}

 

Sublime Text 小技巧

修改字型,避免Color Scheme,覆蓋預設字型造成中文亂碼

"font_face": "Courier New"

禁止索引,讓cpu不會負擔哪麼高

"index_files":false

或是指定部分檔案不索引

"index_exclude_patterns": [*.log]

指定某些檔案不在側邊欄位出現

"file_exclude_patterns": [*.log]

指定資料夾不在側邊欄位出現

"folder_exclude_patterns": ["logs"]

GCP(Google Cloud Platform)筆記|心得

GCP

GCP SKD安裝

install gcloud
https://cloud.google.com/sdk/downloads

安裝

./install.sh

認證授權

gcloud init

設定區域

gcloud config set compute/zone asia-east1-a

建立叢集

gcloud container clusters create [CLUSTER-NAME]

查看叢集

gcloud container clusters list

設定叢集

gcloud container clusters get-credentials [CLUSTER-NAME]

建立永久磁區

gcloud compute disks create --size 200GB [disk name]

刪除永久磁區

gcloud compute disks delete [disk name]

手動建立容器

 

gcloud container builds submit --config cloudbuild.yaml .
gcloud container builds submit --tag gcr.io/[PROJECT_ID]/quickstart-image .

gcloud docker -- push images

 

GCP GIT

設定git 驗證方式

git config credential.helper gcloud.sh

建立專案

gcloud source repos create [REPO_NAME]

設定專案庫

git remoto add google https://xxx

有效地去 – Effective go 正體中文翻譯

簡介

Go 是一門新的程式語言。雖然它從現有的程式語言中借鏡了許多設計理念,但它也有許多與眾不同的特性。若你把用 C++ / Java 撰寫的程式改寫成等價的 Go 程式,恐怕難以得到令人滿意的結果。同樣地,用 Go 語言的角度來解決問題,你可能會寫出有效但不太一樣的程式。換句話說,想要寫出好的 Go 程式,對於 Go 語言特性及慣例的掌握是重要的一環。同時,對於社群慣例 (比如排版、命名方式、程式的建立等等) 也應該要適當的瞭解,這樣其他使用 Go 語言的開發者才容易理解你寫的程式。

這份文件列舉出一些訣竅,讓你寫出清楚、符合 Go 語言特性的程式。這是對於 Go 語言規格書導覽 Go 語言以及 如何撰寫 Go 程式 等三份文件的補充,所以你應該先讀過這三份文件。
繼續閱讀

GoLang Cookie

GoLang Cookie


Go 語言內 struct methods 該使用 pointer 或 value 傳值?

寫入或讀取

如果您需要對 Struct 內的成員進行修改,那請務必使用 Pointer 傳值,相反的,Go 會使用 Copy struct 方式來傳入,但是用此方式你就拿不到修改後的資料。

效能

假設 Struct 內部成員非常的多,請務必使用 Pointer 方式傳入,這樣省下的系統資源肯定比 Copy Value 的方式還來的多。

一致性

在開發團隊內,如果有人使用 Pointer 有人使用 Value 方式,這樣寫法不統一,造成維護效率非常低,所以官方建議,全部使用 Pointer 方式是最好的寫法。

參考網站


Function types

從golang的官方文檔得知function types的解釋是這樣的。

A function type denotes the set of all functions with the same parameter and result types.

先找個例子來看一下:

package main

import "fmt"

// Greeting function types
type Greeting func(name string) string

func say(g Greeting, n string) {
    fmt.Println(g(n))
}

func english(name string) string {
    return "Hello, " + name
}

func main() {
    say(english, "World")
}

輸出

Hello, World

say()函數要求傳入一個Greeting類型,因為english函數的參數和返回值跟Greeting一樣,參考接口的概念這裡可以做類型轉換。我們換個方式來實現上面的功能:

package main

import "fmt"

// Greeting function types
type Greeting func(name string) string

func (g Greeting) say(n string) {
    fmt.Println(g(n))
}

func english(name string) string {
    return "Hello, " + name
}

func main() {
    g := Greeting(english)
    g.say("World")
}

同樣輸出Hello, World,只是給Greeting類型添加了say()方法。上面說了,函數類型是表示所有包含相同參數和返回類型的函數集合。我們在一開始先把func(name string) string這樣的函數聲明成Greeting類型,接著我們通過Greeting(english)將english函數轉換成Greeting類型。通過這個轉換以後,我們就可以借由變量g調用Greeting類型的say()方法。兩段代碼的差異就是go的類型系統添加方法和類C++語言添加類型方法的差異

既然是函數集合,那麼只有一個函數顯然是不足以說明問題的。

package main

import "fmt"

// Greeting function types
type Greeting func(name string) string

func (g Greeting) say(n string) {
    fmt.Println(g(n))
}

func english(name string) string {
    return "Hello, " + name
}

func french(name string) string {
    return "Bonjour, " + name
}

func main() {
    g := Greeting(english)
    g.say("World")
    g = Greeting(french)
    g.say("World")
}

輸出

Hello, World
Bonjour, World

在其他語言裡面,有些函數可以直接作為參數傳遞,有些是以函數指針進行傳遞,但是都沒有辦法像go這樣可以給函數類型「增加」新方法。

回到Go: net/http的HandlerFunc類型,只要Martini的函數遵循文檔中type HandlerFunc func(ResponseWriter, *Request)的要求,就可以轉換成HandlerFunc類型,也就可以調用func (HandlerFunc)ServeHTTP函數。

參考網站