mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-17 08:46:40 +08:00
336 lines
24 KiB
HTML
336 lines
24 KiB
HTML
<!DOCTYPE html>
|
||
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
||
<link rel="icon" href="/static/favicon.png">
|
||
<title>01 基础入门:编写你的第一个 Go 语言程序.md.html</title>
|
||
<!-- Spectre.css framework -->
|
||
<link rel="stylesheet" href="/static/index.css">
|
||
<!-- theme css & js -->
|
||
<meta name="generator" content="Hexo 4.2.0">
|
||
</head>
|
||
<body>
|
||
<div class="book-container">
|
||
<div class="book-sidebar">
|
||
<div class="book-brand">
|
||
<a href="/">
|
||
<img src="/static/favicon.png">
|
||
<span>技术文章摘抄</span>
|
||
</a>
|
||
</div>
|
||
<div class="book-menu uncollapsible">
|
||
<ul class="uncollapsible">
|
||
<li><a href="/" class="current-tab">首页</a></li>
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
<li><a href="../">上一级</a></li>
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/00 开篇词 Go 为开发者的需求设计,带你实现高效工作.md.html">00 开篇词 Go 为开发者的需求设计,带你实现高效工作</a>
|
||
</li>
|
||
<li>
|
||
<a class="current-tab" href="/专栏/22 讲通关 Go 语言-完/01 基础入门:编写你的第一个 Go 语言程序.md.html">01 基础入门:编写你的第一个 Go 语言程序</a>
|
||
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/02 数据类型:你必须掌握的数据类型有哪些?.md.html">02 数据类型:你必须掌握的数据类型有哪些?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/03 控制结构:if、for、switch 逻辑语句的那些事儿.md.html">03 控制结构:if、for、switch 逻辑语句的那些事儿</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/04 集合类型:如何正确使用 array、slice 和 map?.md.html">04 集合类型:如何正确使用 array、slice 和 map?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/05 函数和方法:Go 语言中的函数和方法到底有什么不同?.md.html">05 函数和方法:Go 语言中的函数和方法到底有什么不同?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/06 struct 和 interface:结构体与接口都实现了哪些功能?.md.html">06 struct 和 interface:结构体与接口都实现了哪些功能?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/07 错误处理:如何通过 error、deferred、panic 等处理错误?.md.html">07 错误处理:如何通过 error、deferred、panic 等处理错误?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/08 并发基础:Goroutines 和 Channels 的声明与使用.md.html">08 并发基础:Goroutines 和 Channels 的声明与使用</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/09 同步原语:sync 包让你对并发控制得心应手.md.html">09 同步原语:sync 包让你对并发控制得心应手</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/10 Context:你必须掌握的多线程并发控制神器.md.html">10 Context:你必须掌握的多线程并发控制神器</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/11 并发模式:Go 语言中即学即用的高效并发模式.md.html">11 并发模式:Go 语言中即学即用的高效并发模式</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/12 指针详解:在什么情况下应该使用指针?.md.html">12 指针详解:在什么情况下应该使用指针?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/13 参数传递:值、引用及指针之间的区别?.md.html">13 参数传递:值、引用及指针之间的区别?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/14 内存分配:new 还是 make?什么情况下该用谁?.md.html">14 内存分配:new 还是 make?什么情况下该用谁?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/15 运行时反射:字符串和结构体之间如何转换?.md.html">15 运行时反射:字符串和结构体之间如何转换?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/16 非类型安全:让你既爱又恨的 unsafe.md.html">16 非类型安全:让你既爱又恨的 unsafe</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/17 SliceHeader:slice 如何高效处理数据?.md.html">17 SliceHeader:slice 如何高效处理数据?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/18 质量保证:Go 语言如何通过测试保证质量?.md.html">18 质量保证:Go 语言如何通过测试保证质量?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/19 性能优化:Go 语言如何进行代码检查和优化?.md.html">19 性能优化:Go 语言如何进行代码检查和优化?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/20 协作开发:模块化管理为什么能够提升研发效能?.md.html">20 协作开发:模块化管理为什么能够提升研发效能?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/21 网络编程:Go 语言如何玩转 RESTful API 服务?.md.html">21 网络编程:Go 语言如何玩转 RESTful API 服务?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/22 网络编程:Go 语言如何通过 RPC 实现跨平台服务?.md.html">22 网络编程:Go 语言如何通过 RPC 实现跨平台服务?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/22 讲通关 Go 语言-完/23 结束语 你的 Go 语言成长之路.md.html">23 结束语 你的 Go 语言成长之路</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||
<div class="sidebar-toggle-inner"></div>
|
||
</div>
|
||
<script>
|
||
function add_inner() {
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
inner.classList.add('show')
|
||
}
|
||
function remove_inner() {
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
inner.classList.remove('show')
|
||
}
|
||
function sidebar_toggle() {
|
||
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
let content = document.querySelector('.off-canvas-content')
|
||
if (sidebar_toggle.classList.contains('extend')) { // show
|
||
sidebar_toggle.classList.remove('extend')
|
||
sidebar.classList.remove('hide')
|
||
content.classList.remove('extend')
|
||
} else { // hide
|
||
sidebar_toggle.classList.add('extend')
|
||
sidebar.classList.add('hide')
|
||
content.classList.add('extend')
|
||
}
|
||
}
|
||
function open_sidebar() {
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
sidebar.classList.add('show')
|
||
overlay.classList.add('show')
|
||
}
|
||
function hide_canvas() {
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
sidebar.classList.remove('show')
|
||
overlay.classList.remove('show')
|
||
}
|
||
</script>
|
||
<div class="off-canvas-content">
|
||
<div class="columns">
|
||
<div class="column col-12 col-lg-12">
|
||
<div class="book-navbar">
|
||
<!-- For Responsive Layout -->
|
||
<header class="navbar">
|
||
<section class="navbar-section">
|
||
<a onclick="open_sidebar()">
|
||
<i class="icon icon-menu"></i>
|
||
</a>
|
||
</section>
|
||
</header>
|
||
</div>
|
||
<div class="book-content" style="max-width: 960px; margin: 0 auto;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;">
|
||
<div class="book-post">
|
||
<p id="tip" align="center"></p>
|
||
<div><h1>01 基础入门:编写你的第一个 Go 语言程序</h1>
|
||
<p>从这节课开始,我会带你走进 Go 语言的世界。我会用通俗易懂的语言,介绍 Go 语言的各个知识点,让你可以从零开始逐步学习,再深入它的世界。不管你以前是否接触过 Go 语言,都可以从这个专栏中受益。</p>
|
||
<p>现在,让我以一个经典的例子“Hello World”来带你入门 Go 语言,了解它是如何运行起来的。</p>
|
||
<h3>Hello, 世界</h3>
|
||
<p>如果你学过 C 语言,对这个经典的例子应该不会陌生。通过它,我先带你大概了解一下 Go 语言的一些核心理念,让你对 Go 语言代码有个整体的印象。如下所示:</p>
|
||
<p><em><strong>ch01/main.go</strong></em></p>
|
||
<pre><code>package main
|
||
import "fmt"
|
||
func main() {
|
||
fmt.Println("Hello, 世界")
|
||
}
|
||
</code></pre>
|
||
<p>这五行代码就构成了一个完整的 Go 程序,是不是非常简单?现在我运行这段代码,看看输出的结果,方法是打开终端输入以下命令,然后回车。</p>
|
||
<pre><code>$ go run ch01/main.go
|
||
Hello, 世界
|
||
</code></pre>
|
||
<p>其中 go run ch01/main.go 是我输入的命令,回车后看到的“Hello, 世界”是 Go 程序输出的结果。</p>
|
||
<p>代码中的 go 是一个 Go 语言开发工具包提供的命令,它和你平时常用的 ls 命令一样都是可执行的命令。它可以帮助你运行 Go 语言代码,并进行编译,生成可执行的二进制文件等。</p>
|
||
<p>run 在这里是 go 命令的子命令,表示要运行 Go 语言代码的意思。最后的 ch01/main.go 就是我写的 Go 语言代码文件了。也就是说,整个 go run ch01/main.go 表示要运行 ch01/main.go 里的 Go 语言代码。</p>
|
||
<h3>程序结构分析</h3>
|
||
<p>要让一个 Go 语言程序成功运行起来,只需要 package main 和 main 函数这两个核心部分, package main 代表的是一个可运行的应用程序,而 main 函数则是这个应用程序的主入口。</p>
|
||
<p>在“Hello, 世界”这个简单的示例中,包含了一个 Go 语言程序运行的最基本的核心结构。我们以此为例,来逐一介绍程序的结构,了解 Go 语言的核心概念。</p>
|
||
<ul>
|
||
<li><strong>第一行的 package main</strong> 代表当前的 ch01/main.go 文件属于哪个包,其中 package 是 Go 语言声明包的关键字,main 是要声明的包名。在 Go 语言中 main 包是一个特殊的包,代表你的 Go 语言项目是一个可运行的应用程序,而不是一个被其他项目引用的库。</li>
|
||
<li><strong>第二行的 import "fmt"</strong> 是导入一个 fmt 包,其中 import 是 Go 语言的关键字,表示导入包的意思,这里我导入的是 fmt 包,导入的目的是要使用它,下面会继续讲到。</li>
|
||
<li><strong>第三行的 func main()</strong> 是定义了一个函数,其中 func 是 Go 语言的关键字,表示要定义一个函数或者方法的意思,main 是函数名,() 空括号表示这个 main 函数不接受任何参数。在 Go 语言中 main 函数是一个特殊的函数,它代表整个程序的入口,也就是程序在运行的时候,会先调用 main 函数,然后通过 main 函数再调用其他函数,达到实现项目业务需求的目的。</li>
|
||
<li><strong>第四行的 fmt.Println("Hello, 世界")</strong> 是通过 fmt 包的 Println 函数打印“Hello, 世界”这段文本。其中 fmt 是刚刚导入的包,要想使用一个包,必须先导入。Println 函数是属于包 fmt 的函数,这里我需要它打印输出一段文本,也就是“Hello, 世界”。</li>
|
||
<li><strong>第五行的大括号 }</strong> 表示 main 函数体的结束。现在整个代码片段已经分析完了,运行就可以看到“Hello, 世界”结果的输出。</li>
|
||
</ul>
|
||
<p>从以上分析来看,<strong>Go 语言的代码是非常简洁、完整的核心程序,只需要 package、import、func main 这些核心概念就可以实现。</strong> 在后面的课时中,我还会讲如何使用变量,如何自定义函数等,这里先略过不讲,我们先来看看 Go 语言的开发环境是如何搭建的,这样才能运行上面的 Go 语言代码,让整个程序跑起来。</p>
|
||
<h3>Go 语言环境搭建</h3>
|
||
<p>要想搭建 Go 语言开发环境,需要先下载 Go 语言开发包。你可以从官网 <a href="https://golang.org/dl/">https://golang.org/dl/</a> 和 <a href="https://golang.google.cn/dl/">https://golang.google.cn/dl/</a> 下载(第一个链接是国外的官网,第二个是国内的官网,如果第一个访问不了,可以从第二个下载)。</p>
|
||
<p>下载时可以根据自己的操作系统选择相应的开发包,比如 Window、MacOS 或是 Linux 等,如下图所示:</p>
|
||
<p><img src="assets/CgqCHl-ikW2AdldmAABgiiXVyCo654.png" alt="png" /></p>
|
||
<h4>Windows MSI 下安装</h4>
|
||
<p>MSI 安装的方式比较简单,在 Windows 系统上推荐使用这种方式。现在的操作系统基本上都是 64 位的,所以选择 64 位的 go1.15.windows-amd64.msi 下载即可,如果操作系统是 32 位的,选择 go1.15.windows-386.msi 进行下载。</p>
|
||
<p>下载后双击该 MSI 安装文件,按照提示一步步地安装即可。在默认情况下,Go 语言开发工具包会被安装到 c:\Go 目录,你也可以在安装过程中选择自己想要安装的目录。</p>
|
||
<p>假设安装到 c:\Go 目录,安装程序会自动把 c:\Go\bin 添加到你的 PATH 环境变量中,如果没有的话,你可以通过系统 -> 控制面板 -> 高级 -> 环境变量选项来手动添加。</p>
|
||
<h4>Linux 下安装</h4>
|
||
<p>Linux 系统同样有 32 位和 64 位,你可以根据你的 Linux 操作系统选择相应的压缩包,它们分别是 go1.15.linux-386.tar.gz 和 go1.15.linux-amd64.tar.gz。</p>
|
||
<p>下载成功后,需要先进行解压,假设你下载的是 go1.15.linux-amd64.tar.gz,在终端通过如下命令即可解压:</p>
|
||
<pre><code>sudo tar -C /usr/local -xzf go1.15.linux-amd64.tar.gz
|
||
</code></pre>
|
||
<p>输入后回车,然后输入你的电脑密码,即可解压到 /usr/local 目录,然后把 /usr/local/go/bin 添加到 PATH 环境变量中,就可以使用 Go 语言开发工具包了。</p>
|
||
<p>把下面这段添加到 /etc/profile 或者 $HOME/.profile 文件中,保存后退出即可成功添加环境变量。</p>
|
||
<pre><code>export PATH=$PATH:/usr/local/go/bin
|
||
</code></pre>
|
||
<h4>macOS 下安装</h4>
|
||
<p>如果你的操作系统是 macOS,可以采用 PKG 安装包。下载 go1.15.darwin-amd64.pkg 后,双击按照提示安装即可。安装成功后,路径 /usr/local/go/bin 应该已经被添加到了 PATH 环境变量中,如果没有的话,你可以手动添加,和上面 Linux 的方式一样,把如下内容添加到 /etc/profile 或者 $HOME/.profile 文件保存即可。</p>
|
||
<pre><code>export PATH=$PATH:/usr/local/go/bin
|
||
</code></pre>
|
||
<h4>安装测试</h4>
|
||
<p>以上都安装成功后,你可以打开终端或者命令提示符,输入 go version 来验证 Go 语言开发工具包是否安装成功。如果成功的话,会打印出 Go 语言的版本和系统信息,如下所示:</p>
|
||
<pre><code>$ go version
|
||
go version go1.15 darwin/amd64
|
||
</code></pre>
|
||
<h3>环境变量设置</h3>
|
||
<p>Go 语言开发工具包安装好之后,它的开发环境还没有完全搭建完成,因为还有两个重要的环境变量没有设置,它们分别是 GOPATH 和 GOBIN。</p>
|
||
<ul>
|
||
<li><strong>GOPATH</strong>:代表 Go 语言项目的工作目录,在 Go Module 模式之前非常重要,现在基本上用来存放使用 go get 命令获取的项目。</li>
|
||
<li><strong>GOBIN</strong>:代表 Go 编译生成的程序的安装目录,比如通过 go install 命令,会把生成的 Go 程序安装到 GOBIN 目录下,以供你在终端使用。</li>
|
||
</ul>
|
||
<p>假设工作目录为 /Users/flysnow/go,你需要把 GOPATH 环境变量设置为 /Users/flysnow/go,把 GOBIN 环境变量设置为 $GOPATH/bin。</p>
|
||
<p>在 Linux 和 macOS 下,把以下内容添加到 /etc/profile 或者 $HOME/.profile 文件保存即可。</p>
|
||
<pre><code>export GOPATH=/Users/flysnow/go
|
||
export GOBIN=$GOPATH/bin
|
||
</code></pre>
|
||
<p>在 Windows 操作系统中,则通过控制面板 -> 高级 -> 环境变量选项添加这两个环境变量即可。</p>
|
||
<h3>项目结构</h3>
|
||
<p>采用 Go Module 的方式,可以在任何位置创建你的 Go 语言项目。在整个专栏中,我都会使用这种方式演示 Go 语言示例,现在你先对 Go Module 项目结构有一个大概了解,后面的课时我会详细地介绍 Go Module。</p>
|
||
<p>假设你的项目位置是 /Users/flysnow/git/gotour,打开终端,输入如下命令切换到该目录下:</p>
|
||
<pre><code>$ cd /Users/flysnow/git/gotour
|
||
</code></pre>
|
||
<p>然后再执行如下命令创建一个 Go Module 项目:</p>
|
||
<pre><code>$ go mod init
|
||
</code></pre>
|
||
<p>执行成功后,会生成一个 go.mod 文件。然后在当前目录下创建一个 main.go 文件,这样整个项目目录结构是:</p>
|
||
<pre><code>gotour
|
||
├── go.mod
|
||
├── lib
|
||
└── main.go
|
||
</code></pre>
|
||
<p>其中 main.go 是整个项目的入口文件,里面有 main 函数。lib 目录是项目的子模块,根据项目需求可以新建很多个目录作为子模块,也可以继续嵌套为子模块的子模块。</p>
|
||
<h3>编译发布</h3>
|
||
<p>完成了你的项目后,可以编译生成可执行文件,也可以把它发布到 $GOBIN 目录,以供在终端使用。以“Hello 世界”为例,在项目根目录输入以下命令,即可编译一个可执行文件。</p>
|
||
<pre><code>$ go build ./ch01/main.go
|
||
</code></pre>
|
||
<p>回车执行后会在当前目录生成 main 可执行文件,现在,我们来测试下它是否可用。</p>
|
||
<pre><code>$ ./main
|
||
Hello, 世界
|
||
</code></pre>
|
||
<p>如果成功打印出“Hello, 世界”,证明程序成功生成。</p>
|
||
<p>以上生成的可执行文件在当前目录,也可以把它安装到 $GOBIN 目录或者任意位置,如下所示:</p>
|
||
<pre><code>$ go install ./ch01/main.go
|
||
</code></pre>
|
||
<p>使用 go install 命令即可,现在你在任意时刻打开终端,输入 main 回车,都会打印出“Hello, 世界”,是不是很方便!</p>
|
||
<h3>跨平台编译</h3>
|
||
<p>Go 语言开发工具包的另一强大功能就是可以跨平台编译。什么是跨平台编译呢?就是你在 macOS 开发,可以编译 Linux、Window 等平台上的可执行程序,这样你开发的程序,就可以在这些平台上运行。也就是说,你可以选择喜欢的操作系统做开发,并跨平台编译成需要发布平台的可执行程序即可。</p>
|
||
<p>Go 语言通过两个环境变量来控制跨平台编译,它们分别是 GOOS 和 GOARCH 。</p>
|
||
<ul>
|
||
<li><strong>GOOS</strong>:代表要编译的目标操作系统,常见的有 Linux、Windows、Darwin 等。</li>
|
||
<li><strong>GOARCH</strong>:代表要编译的目标处理器架构,常见的有 386、AMD64、ARM64 等。</li>
|
||
</ul>
|
||
<p>这样通过组合不同的 GOOS 和 GOARCH,就可以编译出不同的可执行程序。比如我现在的操作系统是 macOS AMD64 的,我想编译出 Linux AMD64 的可执行程序,只需要执行 go build 命令即可,如以下代码所示:</p>
|
||
<pre><code>$ GOOS=linux GOARCH=amd64 go build ./ch01/main.go
|
||
</code></pre>
|
||
<p>关于 GOOS 和 GOARCH 更多的组合,参考<a href="https://golang.org/doc/install/source#environment">官方文档</a>的 $GOOS and $GOARCH 这一节即可。</p>
|
||
<h3>Go 编辑器推荐</h3>
|
||
<p>好的编辑器可以提高开发的效率,这里我推荐两款目前最流行的编辑器。</p>
|
||
<p>第一款是 Visual Studio Code + Go 扩展插件,可以让你非常高效地开发,通过官方网站 <a href="https://code.visualstudio.com/">https://code.visualstudio.com/</a> 下载使用。</p>
|
||
<p>第二款是老牌 IDE 公司 JetBrains 推出的 Goland,所有插件已经全部集成,更容易上手,并且功能强大,新手老手都适合,你可以通过官方网站 <a href="https://www.jetbrains.com/go/">https://www.jetbrains.com/go/</a> 下载使用。</p>
|
||
<h3>总结</h3>
|
||
<p>这节课中你学到了如何写第一个 Go 语言程序,并且搭建好了 Go 语言开发环境,创建好了 Go 语言项目,同时也下载好了 IDE 严阵以待,那么现在我就给你留个<strong>小作业</strong>:</p>
|
||
<blockquote>
|
||
<p>改编示例“Hello 世界”的代码,打印出自己的名字。</p>
|
||
</blockquote>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div style="float: left">
|
||
<a href="/专栏/22 讲通关 Go 语言-完/00 开篇词 Go 为开发者的需求设计,带你实现高效工作.md.html">上一页</a>
|
||
</div>
|
||
<div style="float: right">
|
||
<a href="/专栏/22 讲通关 Go 语言-完/02 数据类型:你必须掌握的数据类型有哪些?.md.html">下一页</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||
</div>
|
||
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70996dab8d4a3d60","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
|
||
</body>
|
||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
|
||
<script>
|
||
window.dataLayer = window.dataLayer || [];
|
||
function gtag() {
|
||
dataLayer.push(arguments);
|
||
}
|
||
gtag('js', new Date());
|
||
gtag('config', 'G-NPSEEVD756');
|
||
var path = window.location.pathname
|
||
var cookie = getCookie("lastPath");
|
||
console.log(path)
|
||
if (path.replace("/", "") === "") {
|
||
if (cookie.replace("/", "") !== "") {
|
||
console.log(cookie)
|
||
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
|
||
}
|
||
} else {
|
||
setCookie("lastPath", path)
|
||
}
|
||
function setCookie(cname, cvalue) {
|
||
var d = new Date();
|
||
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
|
||
var expires = "expires=" + d.toGMTString();
|
||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||
}
|
||
function getCookie(cname) {
|
||
var name = cname + "=";
|
||
var ca = document.cookie.split(';');
|
||
for (var i = 0; i < ca.length; i++) {
|
||
var c = ca[i].trim();
|
||
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
|
||
}
|
||
return "";
|
||
}
|
||
</script>
|
||
</html>
|