我们知道golang越来越被非常多的开发人员来开发应用。go语言也能够用于开发Ubuntu Scope。

在今天的教程中。我们将具体介绍怎样使用go语言来开发我们的Scope。这对于非常多的不太熟悉C/C++的开发人员来说,无疑是一个福音。

对我来说,这个语言也是比較新的。假设大家想学习golang的话,建议大家阅读“Go
by Example
”。

对于很多其它的关于Go Scope的开发。能够參阅文章“Go scopes development”。

IDE选择

因为一些原因,眼下我们的Ubuntu SDK并没有支持go语言的Scope的开发。可喜的是,我们能够使用Command Line来完毕我们的开发。俗话说。好镰不误砍柴功。一个好的工具无疑能帮我们更快更好地开发。我眼下使用的编辑器是LiteIDE。这个是转为go语言而设计的IDE,很简洁而使用,建议大家试用。

安装开发环境


我们首先必须安装golang包及相关包:

$sudo apt-get install unity-scope-tool golang git bzr python3-scope-harness mercurial


为了说明问题的方便,大家能够先下载我的模版Scope:

$git clone https://gitcafe.com/ubuntu/goscope.git

在自己的Terminal下键入上述的命令,你就能够在你所在的文件夹下发现一个叫做“goscope”的文件夹:

liuxg@liuxg:~/release/goscope$ ls -l
total 68
-rwxrwxr-x 1 liuxg liuxg 2886 7月 2 12:37 build-click-package.sh
-rwxrwxr-x 1 liuxg liuxg 752 7月 2 12:37 build.sh
-rwxrwxr-x 1 liuxg liuxg 1144 7月 2 12:37 clean.sh
-rw-rw-r-- 1 liuxg liuxg 9835 7月 2 12:37 goscope.go
-rw-rw-r-- 1 liuxg liuxg 329 7月 2 12:37 goscope.ini
-rw-rw-r-- 1 liuxg liuxg 102 7月 2 12:37 goscope-security.json
-rw-rw-r-- 1 liuxg liuxg 8403 7月 2 12:37 icon.jpg
-rw-rw-r-- 1 liuxg liuxg 4851 7月 2 12:37 logo.jpg
-rw-rw-r-- 1 liuxg liuxg 435 7月 2 12:37 manifest.json
-rwxrwxr-x 1 liuxg liuxg 1293 7月 2 12:37 run.sh
-rwxrwxr-x 1 liuxg liuxg 1666 7月 2 12:37 setup-chroot-go.sh
drwxrwxr-x 3 liuxg liuxg 4096 7月 2 12:37 src

从上面的显示中,我们能够看到除了我们期望的goscope.go文件外,我们多了几个脚本来帮我们完毕我们的工作。

我们能够依照例如以下的命令把下载后的script变为能够运行的脚本


$chmod +x *.sh


首先,我们来看一下我们的build.sh。

build.sh


#!/bin/bash

#
# usage: ./build.sh
# it builds project and produces the armhf click package
# ./build.sh -d
# it builds the project and deploy it to the phone
# A developer needs to change the armhf names in the following script according tuo your project
# export GOPATH=`pwd`
go get launchpad.net/go-unityscopes/v2
./setup-chroot-go.sh ubuntu-sdk-15.04 vivid
./build-click-package.sh goscope liu-xiao-guo ubuntu-sdk-15.04 vivid if [ $# -eq 1 ]
then
if [ $1 = "-d" ]
then
echo "Start to deploy to the phone ..."
adb push ./goscope.liu-xiao-guo/goscope.liu-xiao-guo_1.0.0_armhf.click /tmp
adb shell "sudo -iu phablet pkcon --allow-untrusted install-local /tmp/goscope.liu-xiao-guo_1.0.0_armhf.click"
exit 0
fi
fi

从这个脚本中。我们能够看到当脚本运行的时候,它运行:


go get launchpad.net/go-unityscopes/v2

这个语句的作用是从上面的地址处下载最新的“go-unityscope”版本号2。当你们下载完我的模版后。事实上里面已经有一个叫做“src”的文件夹。里面已经包括了全部的所须要的文件。


当我们增加“-d”选项后。这个script将会自己主动帮我们把脚本部署到手机中去。记得依据自己的scope名字不同。须要改动部署部分的click包的文件名称及文件夹名字

setup-chroot-go.sh


#!/bin/bash

# Function that executes a given command and compares its return command with a given one.
# In case the expected and the actual return codes are different it exits
# the script.
# Parameters:
# $1: Command to be executed (string)
# $2: Expected return code (number), Can be not defined.
function executeCommand()
{
# gets the command
CMD=$1
# sets the return code expected
# if it's not definedset it to 0
OK_CODE=$2
if [ -n $2 ]
then
OK_CODE=0
fi
# executes the command
${CMD} # checks if the command was executed successfully
RET_CODE=$?
if [ $RET_CODE -ne $OK_CODE ]
then
echo "ERROR executing command: \"$CMD\""
echo "Exiting..."
exit 1
fi
} # ******************************************************************************
# * MAIN *
# ****************************************************************************** if [ $# -ne 2 ]
then
echo "usage: $0 FRAMEWORK_CHROOT SERIES_CHROOT"
exit 1
fi CHROOT=$1
SERIES=$2 sudo click chroot -aarmhf -f$CHROOT -s $SERIES create
sudo click chroot -aarmhf -f$CHROOT -s $SERIES maint apt-get install golang-go golang-go-linux-arm golang-go-dbus-dev golang-go-xdg-dev golang-gocheck-dev golang-gosqlite-dev golang-uuid-dev libgcrypt20-dev:armhf libglib2.0-dev:armhf libwhoopsie-dev:armhf libdbus-1-dev:armhf libnih-dbus-dev:armhf libsqlite3-dev:armhf crossbuild-essential-armhf echo "Executing go get launchpad.net/go-unityscopes/v2 ...."
GOPATH=`pwd` go get launchpad.net/go-unityscopes/v2
echo "Done."

这个脚本是为了帮我们下载我们所须要的chroots,这样能够进行交叉编译armhf架构从而部署到我们的手机上。假设大家已经安装好自己的Ubuntu SDK。而且已经安装好所须要的armhf chroot,这个script将不会下载不论什么的东西。


build-click-package.sh


#/bin/bash

# Function that executes a given command and compares its return command with a given one.
# In case the expected and the actual return codes are different it exits
# the script.
# Parameters:
# $1: Command to be executed (string)
# $2: Expected return code (number), may be undefined.
function executeCommand()
{
# gets the command
CMD=$1
# sets the return code expected
# if it's not definedset it to 0
OK_CODE=$2
if [ -n $2 ]
then
OK_CODE=0
fi
# executes the command
eval ${CMD} # checks if the command was executed successfully
RET_CODE=$?
if [ $RET_CODE -ne $OK_CODE ]
then
echo ""
echo "ERROR executing command: \"$CMD\""
echo "Exiting..."
exit 1
fi
} # ******************************************************************************
# * MAIN *
# ****************************************************************************** if [ $# -ne 4 ]
then
echo "usage: $0 SCOPE_NAME DEVELOPER_NAME FRAMEWORK_CHROOT SERIES_CHROOT"
exit 1
fi SCOPE_NAME=$1
DEVELOPER_NAME=$2
CHROOT=$3
SERIES=$4 CURRENT_DIR=`pwd` FILE_NAME="${SCOPE_NAME}.${DEVELOPER_NAME}"
MANIFEST_NAME="${SCOPE_NAME}.${DEVELOPER_NAME}" echo -n "Removing ${FILE_NAME} directory... "
executeCommand "rm -rf ./${FILE_NAME}"
echo "Done" echo -n "Creating clean ${FILE_NAME} directory... "
executeCommand "mkdir -p ${FILE_NAME}/${FILE_NAME}"
echo "Done" echo -n "Copying scope ini file... "
executeCommand "cp $SCOPE_NAME.ini ${FILE_NAME}/${FILE_NAME}/${FILE_NAME}_${SCOPE_NAME}.ini"
echo "Done" echo -n "Copying the logo file ... "
executeCommand "cp logo.jpg ${FILE_NAME}/${FILE_NAME}/logo.jpg"
echo "Done" echo -n "Copying the icon file ... "
executeCommand "cp icon.jpg ${FILE_NAME}/${FILE_NAME}/icon.jpg"
echo "Done" echo -n "Setting scope name in ini file..."
executeCommand 'sed -i "s/%SCOPE_NAME%/${FILE_NAME}/g" ${FILE_NAME}/${FILE_NAME}/${FILE_NAME}_${SCOPE_NAME}.ini'
echo "Done" echo -n "Copying scope json files... "
executeCommand "cp *.json ${FILE_NAME}/"
echo "Done" echo -n "Setting scope name in manifest file..."
executeCommand 'sed -i "s/%SCOPE_NAME%/${MANIFEST_NAME}/g" ${FILE_NAME}/manifest.json'
echo "Done" echo -n "Cross compiling ${FILE_NAME}..."
executeCommand "click chroot -aarmhf -f$CHROOT -s $SERIES run CGO_ENABLED=1 GOARCH=arm GOARM=7 PKG_CONFIG_LIBDIR=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig GOPATH=/usr/share/gocode/:$GOPATH CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ go build -ldflags '-extld=arm-linux-gnueabihf-g++' -o ${FILE_NAME}/${FILE_NAME}/${FILE_NAME}"
echo "Done" executeCommand "cd ./${FILE_NAME}" echo -n "Building click package ... "
executeCommand "click build ./"
echo "Done" executeCommand "cd .."

我们能够通过这个脚本来交叉编译我们的goscope armhf click包。使用时。就像上面的build.sh中展示的那样:


$./build-click-package.sh goscope liu-xiao-guo ubuntu-sdk-15.04 vivid

这里,我们把项目的Scope名,开发人员的名字,framework 及Ubuntud的系列号传入就可以。



run.sh


#!/bin/bash

#
# This is the script to build and run the scope on desktop environment.
# A developer needs to change the following variable according to your projectt
#  SCOPE_NAME=goscope
#  DEVELOPER_NAME=liu-xiao-guo
#
# function executeCommand()
{
# gets the command
CMD=$1
# sets the return code expected
# if it's not definedset it to 0
OK_CODE=$2
if [ -n $2 ]
then
OK_CODE=0
fi
# executes the command
eval ${CMD} # checks if the command was executed successfully
RET_CODE=$? if [ $RET_CODE -ne $OK_CODE ]
then
echo ""
echo "ERROR executing command: \"$CMD\""
echo "Exiting..."
exit 1
fi
} export GOPATH=`pwd` SCOPE_NAME=goscope
DEVELOPER_NAME=liu-xiao-guo FILE_NAME="${SCOPE_NAME}.${DEVELOPER_NAME}" echo -n "Removing ${FILE_NAME} directory... "
executeCommand "rm -rf ./${FILE_NAME}"
echo "Done" echo -n "Copying scope ini file... "
executeCommand "cp $SCOPE_NAME.ini ${FILE_NAME}_${SCOPE_NAME}.ini"
echo "Done" echo -n "Setting scope name in ini file..."
executeCommand 'sed -i "s/%SCOPE_NAME%/${FILE_NAME}/g" ${FILE_NAME}_${SCOPE_NAME}.ini'
echo "Done" echo -n "Building the scope"
executeCommand "go build -o ${FILE_NAME}" unity-scope-tool ${FILE_NAME}_${SCOPE_NAME}.ini

这个脚本是为了把我们的Scope在Desktop的环境中进行编译,并使用unity-scope-tool来启动我们的Scope:






clean.sh


#!/bin/bash

#
# This file cleans all of the intermediate files produced during the compilation. For each project
# a developer needs to customize the variables
# SCOPE_NAME
# DEVELOPER_NAME
#
# function executeCommand()
{
# gets the command
CMD=$1
# sets the return code expected
# if it's not definedset it to 0
OK_CODE=$2
if [ -n $2 ]
then
OK_CODE=0
fi
# executes the command
eval ${CMD} # checks if the command was executed successfully
RET_CODE=$?
if [ $RET_CODE -ne $OK_CODE ]
then
echo ""
echo "ERROR executing command: \"$CMD\""
echo "Exiting..."
exit 1
fi
} SCOPE_NAME=goscope
DEVELOPER_NAME=liu-xiao-guo FILE_NAME="${SCOPE_NAME}.${DEVELOPER_NAME}" echo -n "Removing ${FILE_NAME} directory... "
executeCommand "rm -rf ./${FILE_NAME}"
echo "Done" echo -n "Removing ${FILE_NAME}_${SCOPE_NAME}.ini ..."
executeCommand "rm -f ${FILE_NAME}_${SCOPE_NAME}.ini"
echo "Done" echo -n "Removing ${FILE_NAME} ..."
executeCommand "rm -f ${FILE_NAME}"
echo "Done" echo -n "Removing pkg directory ..."
executeCommand "rm -rf pkg"
echo "Done"

这个脚本是为了我们可以删除我们在编译过程中所产生不论什么的中间文件。


goscope.go


package main

import (
"launchpad.net/go-unityscopes/v2"
"log"
"encoding/json"
"net/url"
"net/http"
) const searchCategoryYellow = `{
"schema-version" : 1,
"template" : {
"category-layout" : "vertical-journal",
"card-layout": "horizontal",
"card-size": "small",
"collapsed-rows": 0
},
"components" : {
"title" : "title",
"subtitle":"subtitle",
"summary":"summary",
"art":{
"field": "art",
"aspect-ratio": 1
}
}
}` const searchCategoryTemplate = `{
"schema-version" : 1,
"template" : {
"category-layout" : "carousel",
"card-size": "large",
"overlay" : true
},
"components" : {
"title" : "title",
"art" : {
"field": "art",
"aspect-ratio": 1.6,
"fill-mode": "fit"
}
}
}` // SCOPE *********************************************************************** var scope_interface scopes.Scope type MyScope struct {
BaseURI string
Key string
URI string
Dir string
base *scopes.ScopeBase
} type WathereResponse struct {
WeatherList []Weather `json:"results"`
Date string `json:"date"`
} type Weather struct {
CurrentCity string `json:"currentCity"`
Pm25 string `json:"pm25"`
IndexList []Index `json:"index"`
Weather_datalist []Weather_data `json:"weather_data"`
} type Index struct {
Title string `json:"title"`
Zs string `json:"zs"`
Tipt string `json:"tipt"`
Des string `json:"des"`
} type Weather_data struct {
Date string `json:"date"`
DayPictureUrl string `json:"dayPictureUrl"`
NightPictureUrl string `json:"nightPictureUrl"`
Weather string `json:"weather"`
Wind string `json:"wind"`
Temperature string `json:"temperature"`
} func (s *MyScope) buildUrl(url2 string, params map[string]string) string {
query := make(url.Values)
for key, value := range params {
query.Set(key, value)
}
log.Println(url2 + query.Encode())
return url2 + query.Encode()
} // This is used to get results from a webservice
func (s *MyScope) get(url string, params map[string]string, result interface{}) error {
resp, err := http.Get(s.buildUrl(url, params))
if err != nil {
return err
}
defer resp.Body.Close()
decoder := json.NewDecoder(resp.Body)
return decoder.Decode(result)
} func (s *MyScope) Search(q *scopes.CannedQuery, metadata *scopes.SearchMetadata, reply *scopes.SearchReply, cancelled <-chan bool) error {
root_department := s.CreateDepartments(q, metadata, reply)
reply.RegisterDepartments(root_department) query := q.QueryString()
log.Println(query) // Try to get the city name
loc := metadata.Location()
city := loc.City;
log.Println("city: ", city) if query == "" {
if q.DepartmentID() == "" {
query = city
} else {
query = q.DepartmentID()
}
} log.Println("query: ", query) var response WathereResponse if err := s.get(s.BaseURI, map[string]string{"location": query, "ak": s.Key, "output": "json"}, &response); err != nil {
return err
} else {
log.Println("there is no error!")
} // log.Println(response)
date := response.Date;
log.Println("date: ", date) var cat *scopes.Category; if len(q.QueryString()) == 0 && q.DepartmentID() == "" {
cat = reply.RegisterCategory("weather", query, "", searchCategoryTemplate)
} else {
cat = reply.RegisterCategory("weather", "", "", searchCategoryTemplate)
} for _, data := range response.WeatherList {
result := scopes.NewCategorisedResult(cat)
result.SetURI(s.URI) // log.Println("Current city:", data.CurrentCity)
// log.Println("PM25: ", data.Pm25) var yellocalendar string = ""
for _, index := range data.IndexList {
// log.Println("title: ", index.Title)
// log.Println("zs: ", index.Zs)
// log.Println("tipt: ", index.Tipt)
// log.Println("Des: ", index.Des) yellocalendar += index.Title + " "
yellocalendar += index.Zs + " "
yellocalendar += index.Tipt + " "
yellocalendar += index.Des
} for i, weather := range data.Weather_datalist {
// log.Println("date: ", weather.Date)
// log.Println("dayPictureUrl: ", weather.DayPictureUrl)
// log.Println("nightPictureUrl: ", weather.NightPictureUrl)
// log.Println("weather: ",weather.Weather)
// log.Println("wind: ", weather.Wind)
// log.Println("temperature: ", weather.Temperature) result.SetTitle(weather.Date)
result.SetArt(weather.DayPictureUrl)
result.Set("wind", weather.Wind)
result.Set("weather", weather.Weather)
result.Set("temperature", weather.Temperature) if err := reply.Push(result); err != nil {
return err
} result.SetArt(weather.NightPictureUrl)
if err := reply.Push(result); err != nil {
return err
} // Push the yellow calender now
if i == 0 {
cat1 := reply.RegisterCategory("weather1", "今天天气", "", searchCategoryYellow)
result1 := scopes.NewCategorisedResult(cat1) result1.SetURI(s.URI)
result1.SetTitle(date)
result1.SetArt(weather.DayPictureUrl)
result1.Set("subtitle", weather.Weather + " " + weather.Wind + " " + weather.Temperature + " PMI: " + data.Pm25)
result1.Set("summary", yellocalendar) if err := reply.Push(result1); err != nil {
return err
}
}
}
} return nil
} func (s *MyScope) Preview(result *scopes.Result, metadata *scopes.ActionMetadata, reply *scopes.PreviewReply, cancelled <-chan bool) error {
layout1col := scopes.NewColumnLayout(1)
layout2col := scopes.NewColumnLayout(2)
layout3col := scopes.NewColumnLayout(3) // Single cyolumn layout
layout1col.AddColumn("header", "image", "wind", "weather", "temperature", "summary", "actions") // Two column layout
layout2col.AddColumn("header")
layout2col.AddColumn("image", "wind", "weather", "temperature", "summary", "actions") // Three cokumn layout
layout3col.AddColumn("header")
layout3col.AddColumn("image", "wind", "weather", "temperature","summary", "actions")
layout3col.AddColumn() // Register the layouts we just created
reply.RegisterLayout(layout1col, layout2col, layout3col) header := scopes.NewPreviewWidget("header", "header") // It has title and a subtitle properties
header.AddAttributeMapping("title", "title")
header.AddAttributeMapping("subtitle", "subtitle") // Define the image section
image := scopes.NewPreviewWidget("image", "image")
// It has a single source property, mapped to the result's art property
image.AddAttributeMapping("source", "art") // Define the summary section
description := scopes.NewPreviewWidget("summary", "text")
description.AddAttributeMapping("text", "summary") wind := scopes.NewPreviewWidget("wind", "text")
wind.AddAttributeMapping("text", "wind") weather := scopes.NewPreviewWidget("weather", "text")
weather.AddAttributeMapping("text", "weather") temperature := scopes.NewPreviewWidget("temperature", "text")
temperature.AddAttributeMapping("text", "temperature") // build variant map.
var uri string if err := result.Get("uri", &uri); err != nil {
log.Println(err)
} tuple1 := make(map[string]interface{})
tuple1["id"] = "open"
tuple1["label"] = "Open"
tuple1["uri"] = uri actions := scopes.NewPreviewWidget("actions", "actions")
actions.AddAttributeValue("actions", []interface{}{tuple1}) var summary string
if err := result.Get("summary", &summary); err != nil {
log.Println(err)
} if len(summary) > 0 {
reply.PushWidgets(header, image, description, actions)
} else {
reply.PushWidgets(header, image, wind, weather, temperature, actions)
} return nil
} func (s *MyScope) SetScopeBase(base *scopes.ScopeBase) {
s.base = base
} func (s *MyScope) GetSubdepartments1(query *scopes.CannedQuery,
metadata *scopes.SearchMetadata,
reply *scopes.SearchReply) *scopes.Department {
active_dep, err := scopes.NewDepartment("wuhan", query, "湖北") if err == nil {
// active_dep.SetAlternateLabel("Rock Music Alt")
department, _ := scopes.NewDepartment("武汉", query, "武汉")
active_dep.AddSubdepartment(department) department2, _ := scopes.NewDepartment("宜昌", query, "宜昌")
active_dep.AddSubdepartment(department2) department3, _ := scopes.NewDepartment("随州", query, "随州")
active_dep.AddSubdepartment(department3)
} return active_dep
} func (s *MyScope) GetSubdepartments2(query *scopes.CannedQuery,
metadata *scopes.SearchMetadata,
reply *scopes.SearchReply) *scopes.Department {
active_dep, err := scopes.NewDepartment("changsha", query, "湖南") if err == nil {
department, _ := scopes.NewDepartment("长沙", query, "长沙")
active_dep.AddSubdepartment(department) department2, _ := scopes.NewDepartment("株洲", query, "株洲")
active_dep.AddSubdepartment(department2)
} return active_dep
} func (s *MyScope) CreateDepartments(query *scopes.CannedQuery,
metadata *scopes.SearchMetadata,
reply *scopes.SearchReply) *scopes.Department { department, _ := scopes.NewDepartment("", query, "选择地点") dept1 := s.GetSubdepartments1(query, metadata, reply)
if dept1 != nil {
department.AddSubdepartment(dept1)
} dept2 := s.GetSubdepartments2(query, metadata, reply)
if dept2 != nil {
department.AddSubdepartment(dept2)
} return department
} // MAIN ************************************************************************ func main() {
scope := &MyScope {
BaseURI: "http://api.map.baidu.com/telematics/v3/weather?",
Key: "DdzwVcsGMoYpeg5xQlAFrXQt",
URI: "http://www.weather.com.cn/html/weather/101010100.shtml",
Dir: "",
} scope_interface = scope if err := scopes.Run(scope); err != nil {
log.Fatalln(err)
}
}

这是我们的goscope的go语言程序设计。在这个goscope里,我们使用了百度的天气API来显示天气的数据。

整个scope的设计事实上和C++的Scope设计比較相似,可是显得更加简洁明了。


我们能够通过例如以下的命令来把我们的Scope打包并部署到我们的手机上:

$./build.sh -d

假设我们仅仅想得到armhf的click包,我们能够不须要“-d”參数。

在手机上的执行情况:




   



怎样执行Scope


我们能够在Terminal中:

[plain] view
plain
copy

  1. $chmod +x *.sh

通过上述命令来使得.sh文件变为能够运行的文件

[plain] view
plain
copy

  1. $./run.sh

通过上面的脚本执行。在Desktop上执行我们的Scope

[plain] view
plain
copy

  1. $./build.sh -d

通过我们上面的脚本运行。能够编译goscope。并部署到手机中去

[plain] view
plain
copy

  1. $./clean.sh

通过上面的脚本运行,清除全部的编译的中间文件

使用golang来设计我们的Ubuntu Scope的更多相关文章

  1. 怎样在Ubuntu Scope中定义设置变量并读取

    在本遍文章中,我们来解说怎么对我们的Ubuntu Scope进行设置.对Scope而言,有些时候我们希望可以使用设置来改变我们的显示.或对我们的搜索进行又一次定义.关于很多其它Scope的开发,请參阅 ...

  2. 怎么在Ubuntu Scope中获取location地址信息

    Location信息对非常多有地址进行搜索的应用来说非常重要.比方对dianping这种应用来说.我们能够通过地址来获取当前位置的一些信息.在这篇文章中,我们来介绍怎样获取Scope架构中的位置信息. ...

  3. golang初识 - install go on ubuntu

    WSL: Ubuntu 18.04 1. install go (1) unzip sudo mkdir -p /usr/local/go sudo tar zxvf go1.12.4.linux-a ...

  4. 安装Ubuntu 14.04后要做的5件事情

    转自安装Ubuntu 14.04后要做的5件事情 Ubuntu目前是世界上最流行的Linux操作系统,它提供了桌面版本和服务器版本,其他流行的Linux发行版本如Linux Mint也是基于Ubunt ...

  5. Golang之chan/goroutine(转)

    原文地址:http://tchen.me/posts/2014-01-27-golang-chatroom.html?utm_source=tuicool&utm_medium=referra ...

  6. 从源码(编译)安装golang 二

    h1 { margin-top: 0.6cm; margin-bottom: 0.58cm; direction: ltr; color: #000000; line-height: 200%; te ...

  7. golang使用通道模仿实现valatile语义

        golang团队在sync中提供了很多的原子操作函数,将原子操作转向由单独一个包提供,而不是像Java那样提供各种累,确实上手得更加简单.但是golang原生提供的并发操作没有Java来得丰富 ...

  8. JAVA开发者的Golang快速指南

    Golang作为Docker.Kubernetes和OpenShift等一些酷辣新技术的首选编程语言,越来越受欢迎.尤其它们都是开源的,很多情况下,开源是非常有价值的.深入学习阅Golang等源代码库 ...

  9. golang并发练习代码笔记

    golang语言的精髓就是它的并发机制,十分简单,并且极少数在语言层面实现并发机制的语言,golang被成为网络时代的c语言,golang的缔造者也有c语言的缔造者,Go语言是google 推出的一门 ...

随机推荐

  1. MVC系列学习(十)-生成URL与表单

    本次学习,在路由配置信息中,有两个路由规则,在网站第一次启动的时候,注册了两个路由表 1.动态生成url A.在路由规则中,因为Default在前面,所以最新找到该路由表,此时不管 自己定义的控制器名 ...

  2. MyBatis 配置控制台上显示sql语句(log4j.properties 之三)

    ### direct log messages to stdout ###log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.app ...

  3. 【Java设计模式】工厂模式

    简单工厂模式 简单工厂模式不是23种里的一种,简而言之,就是有一个专门生产某个产品的类.比如下图中的鼠标工厂,专业生产鼠标,给参数0,生产戴尔鼠标,给参数1,生产惠普鼠标. 示例代码: //一个产品接 ...

  4. 一、CSS的基础样式

    CSS的基础样式 border 边框 复合写法 border:border-width  border-style border-color: border-width:边框宽度 top right ...

  5. VC++文件监控 ReadDirectoryChangesW

    #include <windows.h> #include <tchar.h> #include <stdio.h> #include <assert.h&g ...

  6. 宏基因组扩增子图表解读2散点图:组间整体差异分析(Beta多样性)

    散点图 数据点在直角坐标系平面上的分布图.在宏基因组领域,散点图常用于展示样品组间的Beta多样性,常用的分析方法有主成分分析(PCA),主坐标轴分析(PCoA/MDS)和限制条件的主坐标轴分析(CP ...

  7. Python 之动态添加属性以及方法

    import types class Person(object): def __init__(self, newName, newAge): self.name = newName self.age ...

  8. MHA的MySQL高可用方案实战

    功能: 1)master的故障切换(keepalived VIP的飘移) 2)主从复制角色的提升和重新转向 其中master 对外提供写服务,备选master2(实际的slave提供读服务,slave ...

  9. Django - ORM创建基本类

    DBFirst CodeFirst 创建类 1.根据类自动创建数据库表 在app下的models.py中创建表 创建数据库之前,需要在django下的setting.py模块中的INSTALLED_A ...

  10. js的一些工具类

    //写入cookie function setCookie(name, value) {     var Days = 30; //此 cookie 将被保存 30 天     var exp = n ...