Planet Linux of Taiwan

03月23日

AppleBOY's Blog's face
AppleBOY's Blog


縮小 展開

Go 語言的錯誤訊息處理

Go-brown-side.sh 每個語言對於錯誤訊息的處理方式都不同,在學習每個語言時,都要先學會如何在程式內處理錯誤訊息 (Error Handler),而在 Go 語言的錯誤處理是非常簡單,本篇會用簡單的範例教大家 Go 如何處理錯誤訊息。

Go 輸出錯誤訊息

在 Go 語言內有兩種方式讓函示 (function) 可以回傳錯誤訊息,一種是透過 errors 套件或 fmt 套件,先看看 errors 套件使用方式:
package main

import (
    "errors"
    "fmt"
)

func isEnable(enable bool) (bool, error) {
    if enable {
        return false, errors.New("You can't enable this setting")
    }

    return true, nil
}

func main() {
    if _, err := isEnable(true); err != nil {
        fmt.Println(err.Error())
    }
}
請先引入 errors 套件,接著透過 errors.New("message here"),就可以實現 error 錯誤訊息。接著我們打開 errors package 原始碼來看看
package errors

// New returns an error that formats as the given text.
func New(text string) error {
    return &errorString{text}
}

// errorString is a trivial implementation of error.
type errorString struct {
    s string
}

func (e *errorString) Error() string {
    return e.s
}
可以發現 errors 套件內提供了 New 函示,讓開發者可以直接建立 error 物件,並且實現了 error interface。在 Go 語言有定義 error interface 為:
type error interface {
    Error() string
}
只要任何 stuct 有實作 Error() 接口,就可以變成 error 物件。這在下面的自訂錯誤訊息會在提到。除了上面使用 errors 套件外,還可以使用 fmt 套件,將上述程式碼改成:
func isEnable(enable bool) (bool, error) {
    if enable {
        return false, fmt.Errorf("You can't enable this setting")
    }

    return true, nil
}
這樣也可以成功輸出錯誤訊息,請深入看 fmt.Errorf
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
func Errorf(format string, a ...interface{}) error {
    return errors.New(Sprintf(format, a...))
}
你可以發現在 fmt 套件內,引用了 errors 套件,所以基本上本質是一樣的。

Go 錯誤訊息測試

在 Go 語言如何測試錯誤訊息,直接引用 testing 套件
package error

import "testing"

func TestIsMyError(t *testing.T) {
    ok, err := isEnable(true)

    if ok {
        t.Fatal("should be false")
    }

    if err.Error() != "You can't enable this setting" {
        t.Fatal("message error")
    }
}
另外 Go 語言最常用的測試套件 Testify,可以改寫如下:
package error

import (
    "testing"

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

func TestIsEnable(t *testing.T) {
    ok, err := isEnable(true)
    assert.False(t, ok)
    assert.NotNil(t, err)
    assert.Equal(t, "You can't enable this setting", err.Error())
}

Go 自訂錯誤訊息

從上面的例子可以看到,錯誤訊息都是固定的,如果我們要動態改動錯誤訊息,就必須帶變數進去。底下我們來看看如何實現自訂錯誤訊息:
package main

import (
    "fmt"
)

// MyError is an error implementation that includes a time and message.
type MyError struct {
    Title   string
    Message string
}

func (e MyError) Error() string {
    return fmt.Sprintf("%v: %v", e.Title, e.Message)
}

func main() {
    err := MyError{"Error Title 1", "Error Message 1"}
    fmt.Println(err)

    err = MyError{
        Title:   "Error Title 2",
        Message: "Error Message 2",
    }
    fmt.Println(err)
}
也可以把錯誤訊息包成 Package 方式
package error

import (
    "fmt"
)

// MyError is an error implementation that includes a time and message.
type MyError struct {
    Title   string
    Message string
}

func (e MyError) Error() string {
    return fmt.Sprintf("%v: %v", e.Title, e.Message)
}
main.go 就可以直接引用 error 套件
package main

import (
    "fmt"

    my "github.com/go-training/training/example04/error"
)

func main() {
    err := my.MyError{"Error Title 1", "Error Message 1"}
    fmt.Println(err)

    err = my.MyError{
        Title:   "Error Title 2",
        Message: "Error Message 2",
    }
    fmt.Println(err)
}
如何測試錯誤訊息是我們自己所定義的呢?請在 error 套件內加入底下測試函示
func IsMyError(err error) bool {
    _, ok := err.(MyError)
    return ok
}
由於我們實作了 error 接口,只要是 Interface 就可以透過 Type assertion 來判斷此錯誤訊息是否為 MyError
package error

import "testing"

func TestIsMyError(t *testing.T) {
    err := MyError{"title", "message"}

    ok := IsMyError(err)

    if !ok {
        t.Fatal("error is not MyError")
    }

    if err.Error() != "title: message" {
        t.Fatal("message error")
    }
}
這樣在專案裡就可以實現多個錯誤訊息,寫測試時就可以直接判斷錯誤訊息為哪一種自訂格式。

結論

在 Go 裡面寫錯誤訊息真的很方便又很容易,動態訊息請自定,反之,固定訊息請直接宣告 const 就可以了。在寫套件給大家使用時,大部份都是使用固定訊息,如果是大型專案牽扯到資料庫時,通常會用動態自訂錯誤訊息比較多。

上述程式碼請參考這裡

03月22日

shelandy's face
shelandy


縮小 展開

在Linux 下開發 TI lunchpad

安裝其實不難,最重要的是照這裡 用root 身份把 71-ti-permissions.rules 丟進/etc/udev/rules.d/ 重起udev 服務,插上 lunchpad 如MSP-EXP430G2 就會看到/dev/ttyACM0 ,有些如 MSP-EXP430F5529 還會多一個/dev/ttyACM1 ,不過上傳firmware 的port還是選ttyACM0

然後去 http://energia.nu/ 下載新版,這個是Arduino IDE 改的,所以介面非常類似。 lunchpad 比一般的Ardunio Uno 多了一些硬體,如幾個按鍵跟LED ,其他gpio 的用法也類似 有用過Arduino 的人轉換發展環境應該不難。

(以往TI lanuchpad 在Linux 上有cdc-acm 驅動的問題,但是我在mageia kernel 4.4.50 沒事,應該是後來修好了。)

03月17日

shelandy's face
shelandy


縮小 展開

STM32F103RB 改用 Arduino IDE 開發

這個板子有支援can bus 理論上可以把汽車的OBD II 資料拉出來自己監控,但是手上這片STM Nucleo F103RB 要跑mbed 讓我用的很不順手(哪有人改個程式還要上網的道理?),我前年其實針對這有查過Rroger 的github ,但是當時他只列那種小板子,我就放棄了。但我再看了一下網路資料,現在其實支援的不只這些板子,有個日本人有用Rroger 的程式去處理F103RB :Arduino_STM32を試すArduino_STM32 Nucleo STM32F103RB
,所以有STM32 版的朋友可以試著多搜一下

安裝


基本上照著這邊installation指示:解開 github 上master 的壓縮檔,我把那個解開子目錄改成Arduino_STM32,copy 到你自己 Arduino sketches下的 hardware 子目錄下(沒有就自己建)這個不用放在 Arduino 主程式下hardware 子目錄下,你要放在那也可以。

用root 身份執行 tools/linux/install.sh 去增加udev rulues,最後他會抱怨沒法加dialout 進groups 那是因為原本是用一般使用者sudo 的方式,但一般我們能跑Arduino 時都已經先搞定這一部份了

Udev 設好,插進版子就會看到
/dev/sdc        144K   16K  128K   12% /run/media/你的使用名/NUCLEO
mebed 的flash 看起來超大的,這個來存中文字型啥的應該不錯

比較討厭的是每次他都會警告一下,但是不妨正常運作
Could not find boards.txt in /usr/local/arduino-1.6.12/hardware/Arduino_STM32/examples. Is it pre-1.5?

之前好像有看到有人抱怨這張版子layout 怪怪的,可能要改一些設定,不過我直接跑了blink 的程式上去,啥都沒改就燒入正常,可能是近來一票熱心的發展者把此問題解決了

我這板子是看展覽拿免費的,很大一片。但是網路上價錢不貴而且又小,有能力去網購的可以考慮一下拿這代替Arduino nanoSTM32F103C8T6小系統板 單片機 核心板 STM32開發板 學習板 ARM  ¥9.90 ( 約USD 1.42)

sakananote's face
sakananote


縮小 展開

openSUSE Leap 42.2 安裝小記

openSUSE Leap 42.2 安裝小記

桌機的 HD 無預警的升天了......
所以就直接進行升級 :p

記下我安裝 openSUSE Leap 42.2 的相關過程給自己參考
想不到上次裝 openSUSE Leap 42.1 是 2015/12


中文輸入法問題:

因為就算安裝 中文輸入法也沒有出現, 所以就用之前的方式
移除 ibus
#yast2  sw_single

取消 ibus  套件

取消 CD 為安裝來源
# yast2  repositories


Google Chrome:


Freemind:
使用one click install 安裝 http://software.opensuse.org/package/freemind
我是使用 editors 那個來源的 ymp 檔案安裝

.mm 的檔案指定用 freemind  開啟


新增 Packman 套件庫:

使用 #yast2  repositories 手動加入 NCHC Packman 套件庫

#yast2  repositories

URL 為


Firefox download helper:


flash-player:
# zypper   install   flash-player


播放器:


因為 mplayber 與 smplayer 不知道為何播放 .mp4 有點問題, 但是使用 VLC 就沒有問題
所以我就安裝 VLC Media player

並將 .rmvb 以及 .mp4 預設播放器設定為  VLC


Skype:
目前的版本是 4.3.0.37 的版本


使用終端機指令下載
#wget  -O  skype-`date +%F`.rpm   http://www.skype.com/go/getskype-linux-beta-suse

下載的 rpm 會被命名為 skype-日期.rpm


因為目前 rpm base 的OS, skype 只有提供 32 bits 的套件
所以要先預先安裝一些套件

參考 http://en.opensuse.org/SDB:Skype  但是還是有些遺漏, 所以要安裝一些套件


# zypper  -n  install  libqt4-32bit   libqt4-x11-32bit   libpng12-0-32bit
# zypper  -n  install  libXss1-32bit  libQtWebKit4-32bit   libQtWebKit4
# zypper  -n  install  libXv1-32bit  xorg-x11-libs


安裝 skype 套件
# rpm -ivh skype*.rpm


使用 #yast2 sound 調整音效


Dropbox:

使用 # zypper install dropbox 來安裝, 因為發現版本比 software.opensuse.org/search 上面新

安裝完之後在終端機下 dropbox  start  -i  來安裝


安裝 GNOME Control center
# zypper  install  yast2-control-center-gnome

然後修改 /etc/sysconfig/yast2
改為
WANTED_GUI="gtk"

修改 LS_OPTIONS 變數
# vi   /etc/profile.d/ls.bash
把 root 的 LS_OPTIONS 的 -A 移除

.7z 支援:
# zypper  install  p7zip


以下為個人記事

PDF Viewer 安裝:
Foxit
因為預設的 PDF Viewer 中文顯示有問題所以使用 Foxit
https://www.foxitsoftware.com/products/pdf-reader/

Forticlient SSL VPN 安裝:
Dropbox 內2013/packages 的 source code
預先安裝
# zypper install libgthread-2_0-0-32bit

印表機安裝:
# yast2  printer


rdesktop 安裝與測試:
#zypper  install  freerdp

執行方式
#xfreerdp  -g  1280x1024  -u administrator  HOST_IP


VMware workstation Pro 12
http://www.vmware.com/products/workstation/workstation-evaluation.html

安裝 kernel-default-devel  
# zypper   install   kernel-default-devel
# ./VMware-Workstation-Full-12.5.2-4638234.x86_64.bundle

裝完後, 設定取消 share VM access


Yubico Key:
如果 linux 沒有抓到 Yubico 的 U2F Key可以使用以下步驟
讓 linux 支援 Yubico , 我是參考 https://www.yubico.com/faq/enable-u2f-linux/  
作法
存到 /etc/udev/rules.d/70-u2f.rules
將 linux 重開機, 接下來就可以使用了 :-)

smartgit 安裝:

下載 8.0.3

解壓縮到 /opt
# tar  zxvf   smartgit-linux-8_0_3.tar.gz  -C   /opt/

建立 link 讓一般使用者也能使用
# ln  -s   /opt/smartgit/bin/smartgit.sh   /usr/local/bin/smartgit

安裝 git
# zypper  install  git

建立 個人的 ssh key
> ssh-keygen  -t  dsa

將 ssh 的公鑰 id_dsa.pub 新增到 Github 的 Settings -- >  SSH and GPG Keys

接下來就是以一般使用者的身份執行 smartgit 指令
> smartgit

按照上面的參考設定

設定 smart git icon 使用 alacarte

在設定好之後發現無法直接開啟資料夾 ( 資料夾上面按右鍵 -- > Open )
Edit -- > Preferences --> 點選  Tools -- > 點選 Re-Add Defaults 得到解決
2016-11-24 15-48-28 的螢幕擷圖.png


ansible 安裝:
#zypper  install  ansible

安裝 pysphere:

為了 ansible and VMware Module


# zypper  install  python-pysphere


Docker 安裝:

#zypper  install  docker

#systemctl  start  docker
#systemctl  enable   docker

Franz 安裝:

將網路換回 NetworkManager - cause wifi select

~ enjoy it