提示这些代码是因为系统中缺少dialog-like程序,一般出现在最小化安装的ubuntu系统或者debian系统上。
我们可以使用安装软件的方法解决(sudo权限):
apt-get install dialog或apt-get install whiptail
上下文包最佳实践
在Go中使用上下文包有几个最佳实践:
- 使用context.WithCancel,context.WithTimeout或context.WithDeadline创建带有超时或取消信号的上下文。
- 始终将上下文作为第一个参数传递给可能需要很长时间才能完成的函数,例如网络请求或数据库查询。
- 使用context.Value存储和检索与上下文关联的值,例如用户ID或请求ID。
- 使用context.WithValue基于现有上下文创建新上下文,并将其他值与其关联。
- 检查上下文的Done通道,查看它是否已被取消。
- 在整个应用程序中使用上下文包来传播请求范围的值和取消信号,而不是使用全局变量或手动信号。
- 避免使用context.Background(),因为它没有超时或取消信号,而是使用context.TODO() 表示上下文稍后将被调用方替换。
- 不要将上下文存储在结构中,而是将它们作为参数传递给函数。
- 始终检查上下文感知函数的错误返回值,以查看上下文是否被取消或超时。
Go中的上下文包用于跨API边界传递请求范围的值、取消信号和截止时间。它可用于存储元数据、取消信号、超时和其他请求范围的值。上下文包提供了一种取消长时间运行的操作以及跨API边界存储元数据的方法。它通常与http包一起使用,以管理HTTP请求的请求范围值和取消信号。
它允许您在多个函数调用和goroutine之间传播请求范围的值,从而更轻松地管理应用程序中的信息流。
context.Context是使用context.With*函数创建,例如context.WithValue,context.WithCancel 或 context.WithTimeout。这些函数返回新的上下文,携带指定值或信号的上下文值。
context.Context可以作为参数传递给需要访问请求范围值或侦听取消信号的函数和方法。然后,这些函数可以使用context.Value和context.Done访问上下文中存储的值和信号的done方法。
在需要取消长时间运行的操作或跨多个goroutine传播请求范围的值的情况下,上下文包特别有用。它通常用于服务器端编程和其他并发方案。
应始终将上下文作为第一个参数传递给执行可能被取消的工作的任何函数。
例如,HTTP服务器可以使用上下文在客户端断开连接时取消请求的工作,数据库包可以使用上下文来实现可取消的查询,等等。
context包定义了 Context 类型,该类型是一个Go接口,具有四个方法,分别名为Deadline()、Done()、Err() 和Value():
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done()
Err()
Value(key)
}
上下文接口定义的方法
方法 | 描述 |
---|---|
Value(key) | 返回对应的值 |
Done() | 此方法返回可用于接收取消通知的频道 |
Deadline() | 此方法返回time.Time, 表示请求的截止日期,如果没有指定截止日期,则布尔值为false。 |
Err() | 此方法返回一个错误,指示完成通道接收信号的原因。上下文包定义了两个可用于比较错误的变量:Canceled表示请求已取消,DeadlineExeeded表示截止日期已过。 |
用于创建上下文值的上下文包函数
方法 | 描述 |
---|---|
Background() | 此方法返回默认上下文,从中派生其他上下文。 |
WithCancel(ctx) | 此方法返回一个上下文和一个取消函数。 |
WithDeadline(ctx, time) | 此方法返回一个带有截止日期的上下文,该截止日期用time.Time表示值。 |
WithTimeout(ctx, duration) | 此方法返回一个带有截止日期的上下文,该截止日期用time.Time表示值。 |
WithValue(ctx, key, val) | 此方法返回一个包含指定键值对的上下文。 |
context.WithCancel
下面是一个示例,说明context.WithCancel可以在Go中使用:
package main
import (
"context"
"fmt"
"time"
)
func doWork(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Work done!")
return
default:
fmt.Println("Working...")
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // 推迟执行cancel
go doWork(ctx)
// Wait for a while before canceling the context
select {
case <-ctx.Done():
case <-time.After(time.Second * 3):
cancel()
}
}
在此示例中,我们使用context创建一个新的上下文 ctx.WithCancel(context.background())中。context.Background() 函数返回一个空的context。context.WithCancel 返回一个新的上下文和一个取消函数。我们推迟取消函数,以便在主函数退出时调用它。在 doWork 函数中,它将检查上下文是否已完成,如果是,则返回该函数。
在main函数中,我们正在运行一个goroutine,并通过传递上下文来完成其中的工作。等待3秒后,main函数会通过调用cancel函数来取消上下文,这将使上下文的Done通道关闭。因此,doWork函数将从Done通道接收,打印 "Work done!" 并返回。
context.WithTimeout
在Go中,您可以使用context.WithTimeout函数创建一个新上下文,该上下文在指定的超时时间过后被取消。该函数采用两个参数:现有上下文和超时持续时间。
下面是如何使用上下文的示例。WithTimeout创建在5秒后取消的上下文:
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
// Do some work
select {
case <-ctx.Done():
fmt.Println("Work completed")
case <-time.After(10 * time.Second):
fmt.Println("Work took longer than 10 seconds")
}
}
在此示例中,上下文是通过调用context.WithTimeout与后台上下文5秒的超时创建。该函数返回一个新上下文和一个用于取消上下文的函数。cancel函数在defer语句中调用,以确保在函数返回时取消上下文。select语句用于等待上下文完成或超时结束。
您还可以使用ctx检查上下文是否已完成。Done() 通道,您可以在select语句或循环中使用此通道来检查上下文是否完成,如果完成则意味着上下文已过期。
context.WithDeadline
在Go中,context.WithDeadline 函数创建具有关联截止时间的新上下文。截止日期是一个特定的时间点,在此时间点之后,上下文将被视为"死亡",任何相关工作都将被取消。该函数接受两个参数:现有上下文和截止时间。它返回一个新的上下文,该上下文将在指定的截止时间取消。
下面是一个示例:
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx := context.Background()
deadline := time.Now().Add(time.Second * 5)
ctx, cancel := context.WithDeadline(ctx, deadline)
defer cancel()
select {
case <-time.After(time.Second * 10):
fmt.Println("overslept")
case <-ctx.Done():
fmt.Println(ctx.Err())
}
}
在此示例中,将创建一个背景上下文,然后设置未来5秒的截止时间。WithDeadline 函数用于基于背景上下文创建具有指定截止时间的新上下文。select语句用于等待上下文被取消或等待10秒过去。如果在10秒之前取消上下文,它将打印错误消息上下文截止时间超过,否则将打印"overslept"
使用Context的SQL查询超时
要在Golang中使用超时的SQL查询,您可以使用上下文包来设置查询执行的截止时间。首先,使用上下文创建具有超时的context.WithTimeout函数。然后,将上下文作为第一个参数传递给查询执行函数(例如db.QueryContext() 或db.ExecContext())。
下面是如何为SELECT查询设置1秒超时的示例:
package main
import (
"context"
"database/sql"
"fmt"
"time"
)
func main() {
// Open a connection to the database
db, _ := sql.Open("driverName", "dataSourceName")
// Create a context with a timeout of 1 second
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// Execute the query with the context
rows, err := db.QueryContext(ctx, "SELECT * FROM table")
if err != nil {
fmt.Println(err)
}
defer rows.Close()
// Handle the query results
// ...
}
使用上下文超时读取文件
在Go中,可以使用上下文包来设置读取文件的超时时间。下面是一个示例:
package main
import (
"context"
"fmt"
"io/ioutil"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
data, err := ioutil.ReadFile("example.txt", ctx)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(data))
}
在此示例中,我们首先使用context创建一个超时为2秒的context.WithTimeout。然后,我们将此上下文传递给ioutil。ReadFile读取文件"example.txt"的内容。如果读取文件的时间超过2秒,则上下文的Done通道将关闭,并且ioutil.ReadFile返回错误。
将上下文用于HTTP
在Go中,您可以使用上下文包来设置HTTP请求的超时。下面是一个示例:
package main
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
req, err := http.NewRequest("GET", "https://example.com", nil)
if err != nil {
fmt.Println("Error:", err)
return
}
req = req.WithContext(ctx)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(body))
}
在此示例中,我们首先使用context创建一个超时为2秒的context.WithTimeout。然后,我们使用req.WithContext(ctx) 将此上下文附加到HTTP请求中。当我们使用http.Client.Do方法发出请求时,如果在收到响应之前关闭了上下文的Done通道,它将自动取消请求。
您还可以使用客户端库(如golang.org/x/net/context/ctxhttp)发出带有上下文的http请求,该库具有Get和Post方法,该方法将上下文作为第一个参数并返回响应和错误。
package main
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"time"
"golang.org/x/net/context/ctxhttp"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
resp, err := ctxhttp.Get(ctx, nil, "https://example.com")
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(body))
}
此示例使用ctxhttp.Get方法向"https://example.com"发出GET请求,超时为2秒。
请务必注意,在这两种情况下,如果上下文关闭了Done通道,则请求将被取消,但不会关闭连接。应用程序负责关闭连接。
使用Context作为键值存储
在Go中,您可以使用上下文包来存储可以与请求或一段代码一起传递的键值数据对。这允许您将其他信息与请求或代码段相关联,而不必将其作为显式参数传递。下面是一个示例:
package main
import (
"context"
"fmt"
)
func main() {
ctx := context.WithValue(context.Background(), "user_id", "12345")
// use the context in a function
processRequest(ctx)
}
func processRequest(ctx context.Context) {
userID := ctx.Value("user_id").(string)
fmt.Println("User ID:", userID)
}
在此示例中,我们首先使用context创建一个上下文。WithValue方法。我们传递上下文。Background() 作为父上下文,以及方法的键值对 "user_id" 和 "12345"。然后,我们将此上下文传递给processRequest函数。在函数中,我们使用Value方法从上下文中检索"user_id"值,并将其打印出来。
请务必注意,上下文值仅用于传输进程和API边界的请求范围数据,而不用于将可选参数传递给函数。如果需要将可选参数传递给函数,最好使用结构或函数选项模式。
此外,上下文值不是线程安全的,如果您处于并发环境中,请使用sync.Map或同等产品。
嵌入content示例
import (
"context"
"fmt"
"log"
"os"
"github.com/google/generative-ai-go/genai"
"google.golang.org/api/option"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("API_KEY")))
if err != nil {
log.Fatal(err)
}
defer client.Close()
em := client.EmbeddingModel("embedding-001")
res, err := em.EmbedContent(ctx, genai.Text("cheddar cheese"))
if err != nil {
panic(err)
}
fmt.Println(res.Embedding.Values)
}
代理服务器是一种服务器应用程序,充当最终用户和Internet资源之间的网关。通过代理服务器,最终用户能够出于各种目的控制和监视其Web流量,包括隐私、安全和缓存。例如,您可以使用代理服务器从与您自己的IP地址不同的IP地址发出Web请求。您还可以使用代理服务器来研究不同司法管辖区的网络服务方式,或避免某些监视或网络流量限制方法。
Dante 是一个稳定、流行、开源的SOCKS代理。在本教程中,您将安装和配置Dante以在Ubuntu 20.04服务器上提供SOCKS代理。
先决条件
要完成本指南,您将需要:
- Ubuntu 20.04服务器和具有sudo权限的非root用户。您可以在我们的Ubuntu 20.04初始服务器设置指南中了解有关如何设置具有这些权限的用户的更多信息。
在本教程中,您将使用域名your_domain,但应将其替换为您自己的域名或IP地址。
第1步 — 安装Dante
Dante是一个开源的SOCKS代理服务器。SOCKS是一种不太广泛使用的协议,但它对于某些点对点应用程序更有效,并且对于某些类型的流量,它比HTTP更受欢迎。首先,以非root用户身份运行以下命令,以更新软件包列表并安装Dante:
sudo apt update
sudo apt install dante-server
Dante还会自动设置后台服务,并在安装后启动。但是,它被设计为在首次运行时正常退出并显示错误消息,因为它在出厂时禁用了所有功能。您可以使用以下命令进行验证:systemctl
systemctl status danted.service
Output● danted.service - SOCKS (v4 and v5) proxy daemon (danted)
Loaded: loaded (/lib/systemd/system/danted.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Wed 2021-12-15 21:48:22 UTC; 1min 45s ago
Docs: man:danted(8)
man:danted.conf(5)
Main PID: 14496 (code=exited, status=1/FAILURE)
Dec 15 21:48:21 proxies systemd[1]: Starting SOCKS (v4 and v5) proxy daemon (danted)...
Dec 15 21:48:22 proxies systemd[1]: Started SOCKS (v4 and v5) proxy daemon (danted).
Dec 15 21:48:22 proxies danted[14496]: Dec 15 21:48:22 (1639604902.102601) danted[14496]: warning: checkconfig(): no socks authentication methods enabled. This means all socks requests will be blocked after negotiation. Perhaps this is not intended?
要成功启动Dante的服务,您需要在配置文件中启用它们。
默认情况下,Dante的配置文件在 中提供。如果您使用或您喜欢的文本编辑器打开此文件,您将看到一长串配置选项,所有这些选项都被禁用。您可以尝试浏览此文件并逐行启用某些选项,但实际上删除此文件并从头开始替换它会更有效、更易读。不要担心这样做。您可以随时通过导航到其在线手册来查看Dante的默认配置,如果您愿意,您甚至可以从Ubuntu的软件包列表中手动重新下载软件包以重新获取库存配置文件。同时,继续删除它:/etc/danted.confnano
sudo rm /etc/danted.conf
现在,您可以用更简洁的内容替换它。如果文件不存在,使用文本编辑器打开文件将自动创建该文件,因此通过使用或您喜欢的文本编辑器,您现在应该得到一个空的配置文件:nano
sudo nano /etc/danted.conf
添加以下内容:
/etc/danted.conf文件
logoutput: syslog
user.privileged: root
user.unprivileged: nobody
# The listening network interface or address.
internal: 0.0.0.0 port=1080
# The proxying network interface or address.
external: eth0
# socks-rules determine what is proxied through the external interface.
socksmethod: username
# client-rules determine who can connect to the internal interface.
clientmethod: none
client pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
}
socks pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
}
现在,您有一个可用的SOCKS服务器配置,该配置在端口1080上运行,这是SOCKS的常见约定。您还可以逐行分解此配置文件的其余部分:
- logoutput指Dante将如何记录连接,在本例中为常规系统日志记录
- user.privileged允许Dante具有检查权限的权限root
- user.unprivileged不授予服务器以非特权用户身份运行的任何权限,因为在不授予更精细的权限时,这是不必要的
- internal连接详细信息指定运行服务的端口以及可以连接的IP地址
- external连接详细信息指定用于出站连接的网络接口,默认情况下在大多数服务器上eth0
其余的配置详细信息涉及身份验证方法,下一节将对此进行讨论。如果您使用以下命令,请不要忘记在防火墙中打开端口1080:
sudo ufw allow 1080
此时,您可以重新启动Dante并连接到它,但您将拥有一个向全世界开放的SOCKS服务器,您可能不想要它,因此您将首先学习如何保护它。
第2步 — 保护Dante
如果您到目前为止遵循了本教程,Dante将使用常规的Linux用户帐户进行身份验证。这很有帮助,但用于该连接的密码将通过纯文本发送,因此创建一个没有任何其他登录权限的专用SOCKS用户非常重要。为此,您将使用不会将登录shell分配给用户的标志,然后设置密码:
sudo useradd -r -s /bin/false your_dante_user
sudo passwd your_dante_user
您还需要避免通过不安全的无线连接登录此帐户或过于广泛地共享服务器。否则,恶意行为者可以并且将会反复尝试登录。
Dante支持其他身份验证方法,但许多将连接到SOCKS代理的客户端(即应用程序)仅支持基本的用户名和密码身份验证,因此您可能希望将该部分保持原样。作为替代方法,您可以做的是将访问限制为仅特定IP地址。这不是最复杂的选择,但考虑到这里使用的技术组合,这是一个明智的选择。您可能已经从我们的先决条件教程中学习了如何限制对特定IP地址的访问,但您也可以直接在Dante中执行此操作。编辑您的 :
sudo nano /etc/danted.conf
/etc/danted.conf文件
…
client pass {
from: your_ip_address/0 to: 0.0.0.0/0
}
为了支持多个IP地址,您可以使用 CIDR表示法,或者只添加另一个配置块:client pass {}
/etc/danted.conf文件
client pass {
from: your_ip_address/0 to: 0.0.0.0/0
}
client pass {
from: another_ip_address/0 to: 0.0.0.0/0
}
之后,您终于可以使用配置更改重新启动Dante。
sudo systemctl restart danted.service
这一次,当您检查服务状态时,您应该看到它正在运行,没有任何错误:
systemctl status danted.service
Output● danted.service - SOCKS (v4 and v5) proxy daemon (danted)
Loaded: loaded (/lib/systemd/system/danted.service; enabled; vendor preset: enable>
Active: active (running) since Thu 2021-12-16 18:06:26 UTC; 24h ago
在下一步中,您将最终连接到您的代理。
第3步 — 通过Dante连接
为了演示您的Dante服务器,您将使用一个名为 的命令行程序,该程序在发出不同类型的Web请求时很受欢迎。通常,如果要验证给定连接在理想情况下是否应在浏览器中工作,则应始终首先使用 进行测试。为此,您将在本地计算机上使用curl – 默认情况下,它安装在所有现代Windows、Mac和Linux环境中,因此您可以打开任何本地shell来运行此命令:
curl -v -x socks5://your_dante_user:your_dante_password@your_server_ip:1080 http://www.google.com/
Output* Trying 138.197.103.77...
* TCP_NODELAY set
* SOCKS5 communication to www.google.com:80
* SOCKS5 connect to IPv4 142.250.189.228 (locally resolved)
* SOCKS5 request granted.
* Connected to 138.197.103.77 (138.197.103.77) port 1080 (#0)
> GET / HTTP/1.1
…
声明接口类型
接口是一种抽象类型。
接口描述方法集的所有方法,并为每个方法提供签名。
若要创建接口,请使用interface关键字,后跟包含方法名称列表的大括号,以及方法应具有的任何参数或返回值。
// Declare an Interface Type and methods does not have a body
type Employee interface {
PrintName() string // Method with string return type
PrintAddress(id int) // Method with int parameter
PrintSalary(b int, t int) float64 // Method with parameters and return type
}
接口充当方法集的蓝图,它们必须在使用之前实现。满足接口的类型即实现该接口。
定义满足接口的类型
使用两种方法定义名为Employee的接口类型。然后,它定义一个名为Emp的类型,该类型满足员工。
我们在Emp上定义了满足员工所需的所有方法
package main
import "fmt"
// 声明接口
type Employee interface {
PrintName(name string)
PrintSalary(basic int, tax int) int
}
// Emp用户自定义类型
type Emp int
// 实现接口方法
func (e Emp) PrintName(name string) {
fmt.Println("Employee Id:\t", e)
fmt.Println("Employee Name:\t", name)
}
// 实现接口方法
func (e Emp) PrintSalary(basic int, tax int) int {
var salary = (basic * tax) / 100
return basic - salary
}
func main() {
var e1 Employee
e1 = Emp(1)
e1.PrintName("John Doe")
fmt.Println("Employee Salary:", e1.PrintSalary(25000, 5))
}
如果一个类型具有接口中声明的所有方法,则不需要进一步的声明来显式表示Emp满足 Employee。
声明一个以Employee作为其类型的e1变量,然后创建一个Emp值并将其分配给 e1。
定义满足多个接口的类型
接口允许任何用户定义类型同时满足多种接口类型。
使用类型断言,您可以获取具体类型的值,并且可以调用在其他接口上定义的方法,但不是满足接口的一部分。
package main
import "fmt"
type Polygons interface {
Perimeter()
}
type Object interface {
NumberOfSide()
}
type Pentagon int
func (p Pentagon) Perimeter() {
fmt.Println("Perimeter of Pentagon", 5*p)
}
func (p Pentagon) NumberOfSide() {
fmt.Println("Pentagon has 5 sides")
}
func main() {
var p Polygons = Pentagon(50)
p.Perimeter()
var o Pentagon = p.(Pentagon)
o.NumberOfSide()
var obj Object = Pentagon(50)
obj.NumberOfSide()
var pent Pentagon = obj.(Pentagon)
pent.Perimeter()
}
当用户定义类型实现接口类型声明的方法集时,可以将用户定义类型的值分配给接口类型的值。此赋值将用户定义类型的值存储到接口值中。对接口值进行方法调用时,将执行存储的用户定义值的等效方法。由于任何用户定义类型都可以实现任何接口,因此针对接口值的方法调用本质上是多态的。此关系中的用户定义类型通常称为具体类型。
通用方法接口
两个或多个接口可以在方法集列表中具有一个或多个常用方法。在这里,Structure是Vehicle和Human两个界面之间的常用方法。
package main
import "fmt"
type Vehicle interface {
Structure() []string // Common Method
Speed() string
}
type Human interface {
Structure() []string // Common Method
Performance() string
}
type Car string
func (c Car) Structure() []string {
var parts = []string{"ECU", "Engine", "Air Filters", "Wipers", "Gas Task"}
return parts
}
func (c Car) Speed() string {
return "200 Km/Hrs"
}
type Man string
func (m Man) Structure() []string {
var parts = []string{"Brain", "Heart", "Nose", "Eyelashes", "Stomach"}
return parts
}
func (m Man) Performance() string {
return "8 Hrs/Day"
}
func main() {
var bmw Vehicle
bmw = Car("World Top Brand")
var labour Human
labour = Man("Software Developer")
for i, j := range bmw.Structure() {
fmt.Printf("%-15s <=====> %15s\n", j, labour.Structure()[i])
}
}
输出
ECU <=====> Brain
Engine <=====> Heart
Air Filters <=====> Nose
Wipers <=====> Eyelashes
Gas Task <=====> Stomach
接受变量地址的接口
Print()方法接受接收器指针。因此,接口还必须接受接收器指针。
如果方法接受类型值,则接口必须接收类型值;如果方法具有指针接收器,则接口必须接收相应类型的变量的地址。
package main
import "fmt"
type Book struct {
author, title string
}
type Magazine struct {
title string
issue int
}
func (b *Book) Assign(n, t string) {
b.author = n
b.title = t
}
func (b *Book) Print() {
fmt.Printf("Author: %s, Title: %s\n", b.author, b.title)
}
func (m *Magazine) Assign(t string, i int) {
m.title = t
m.issue = i
}
func (m *Magazine) Print() {
fmt.Printf("Title: %s, Issue: %d\n", m.title, m.issue)
}
type Printer interface {
Print()
}
func main() {
var b Book
var m Magazine
b.Assign("Jack Rabbit", "Book of Rabbits")
m.Assign("Rabbit Weekly", 26)
var i Printer
fmt.Println("Call interface")
i = &b
i.Print()
i = &m
i.Print()
}
空接口类型
类型接口{}称为空接口,它用于接受任何类型的值。空接口没有任何满足它所需的方法,因此每种类型都满足它。
package main
import "fmt"
func printType(i interface{}) {
fmt.Println(i)
}
func main() {
var manyType interface{}
manyType = 100
fmt.Println(manyType)
manyType = 200.50
fmt.Println(manyType)
manyType = "Germany"
fmt.Println(manyType)
printType("Go programming language")
var countries = []string{"india", "japan", "canada", "australia", "russia"}
printType(countries)
var employee = map[string]int{"Mark": 10, "Sandy": 20}
printType(employee)
country := [3]string{"Japan", "Australia", "Germany"}
printType(country)
}
manyType变量被声明为类型接口 {},并且能够为其分配不同类型的值。printType()函数采用类型接口{}的参数,因此该函数可以采用任何有效类型的值。
输出
100
200.5
Germany
Go programming language
[india japan canada australia russia]
map[Mark:10 Sandy:20]
[Japan Australia Germany]
多态性
多态性是编写代码的能力,这些代码可以通过类型实现来承担不同的行为。
我们声明了一个名为五边形、六边形、八边形和十边形的结构,其中包含Geometry接口的实现。
package main
import (
"fmt"
)
type Geometry interface {
Edges() int
}
type Pentagon struct{}
type Hexagon struct{}
type Octagon struct{}
type Decagon struct{}
func (p Pentagon) Edges() int { return 5 }
func (h Hexagon) Edges() int { return 6 }
func (o Octagon) Edges() int { return 8 }
func (d Decagon) Edges() int { return 10 }
func Parameter(geo Geometry, value int) int {
num := geo.Edges()
calculation := num * value
return calculation
}
func main() {
p := new(Pentagon)
h := new(Hexagon)
o := new(Octagon)
d := new(Decagon)
g := [...]Geometry{p, h, o, d}
for _, i := range g {
fmt.Println(Parameter(i, 5))
}
}
输出
25
30
40
50
我们有多态Edges()函数,它接受实现Geometry接口的值。使用多态方法,Parameter()使用传入的每个具体类型值。
接口嵌入
接口可以嵌入其他接口,此行为是接口多态性的一个方面,称为临时多态性。
package main
import "fmt"
type Geometry interface {
Edges() int
}
type Polygons interface {
Geometry // 嵌入接口
}
type Pentagon int
type Hexagon int
type Octagon int
type Decagon int
func (p Pentagon) Edges() int { return 5 }
func (h Hexagon) Edges() int { return 6 }
func (o Octagon) Edges() int { return 8 }
func (d Decagon) Edges() int { return 10 }
func main() {
p := new(Pentagon)
h := new(Hexagon)
o := new(Octagon)
d := new(Decagon)
polygons := [...]Polygons{p, h, o, d}
for i := range polygons {
fmt.Println(polygons[i].Edges())
}
}
当一种类型嵌入到另一种类型中时,嵌入类型的方法可用于嵌入类型。嵌入式接口的方法可供嵌入接口访问。
文件扩展名 | Content-Type(Mime-Type) | 文件扩展名 | Content-Type(Mime-Type) |
---|---|---|---|
.*( 二进制流,不知道下载文件类型) | application/octet-stream | .tif | image/tiff |
.001 | application/x-001 | .301 | application/x-301 |
.323 | text/h323 | .906 | application/x-906 |
.907 | drawing/907 | .a11 | application/x-a11 |
.acp | audio/x-mei-aac | .ai | application/postscript |
.aif | audio/aiff | .aifc | audio/aiff |
.aiff | audio/aiff | .anv | application/x-anv |
.asa | text/asa | .asf | video/x-ms-asf |
.asp | text/asp | .asx | video/x-ms-asf |
.au | audio/basic | .avi | video/avi |
.awf | application/vnd.adobe.workflow | .biz | text/xml |
.bmp | application/x-bmp | .bot | application/x-bot |
.c4t | application/x-c4t | .c90 | application/x-c90 |
.cal | application/x-cals | .cat | application/vnd.ms-pki.seccat |
.cdf | application/x-netcdf | .cdr | application/x-cdr |
.cel | application/x-cel | .cer | application/x-x509-ca-cert |
.cg4 | application/x-g4 | .cgm | application/x-cgm |
.cit | application/x-cit | .class | java/* |
.cml | text/xml | .cmp | application/x-cmp |
.cmx | application/x-cmx | .cot | application/x-cot |
.crl | application/pkix-crl | .crt | application/x-x509-ca-cert |
.csi | application/x-csi | .css | text/css |
.cut | application/x-cut | .dbf | application/x-dbf |
.dbm | application/x-dbm | .dbx | application/x-dbx |
.dcd | text/xml | .dcx | application/x-dcx |
.der | application/x-x509-ca-cert | .dgn | application/x-dgn |
.dib | application/x-dib | .dll | application/x-msdownload |
.doc | application/msword | .dot | application/msword |
.drw | application/x-drw | .dtd | text/xml |
.dwf | Model/vnd.dwf | .dwf | application/x-dwf |
.dwg | application/x-dwg | .dxb | application/x-dxb |
.dxf | application/x-dxf | .edn | application/vnd.adobe.edn |
.emf | application/x-emf | .eml | message/rfc822 |
.ent | text/xml | .epi | application/x-epi |
.eps | application/x-ps | .eps | application/postscript |
.etd | application/x-ebx | .exe | application/x-msdownload |
.fax | image/fax | .fdf | application/vnd.fdf |
.fif | application/fractals | .fo | text/xml |
.frm | application/x-frm | .g4 | application/x-g4 |
.gbr | application/x-gbr | . | application/x- |
.gif | image/gif | .gl2 | application/x-gl2 |
.gp4 | application/x-gp4 | .hgl | application/x-hgl |
.hmr | application/x-hmr | .hpg | application/x-hpgl |
.hpl | application/x-hpl | .hqx | application/mac-binhex40 |
.hrf | application/x-hrf | .hta | application/hta |
.htc | text/x-component | .htm | text/html |
.html | text/html | .htt | text/webviewhtml |
.htx | text/html | .icb | application/x-icb |
.ico | image/x-icon | .ico | application/x-ico |
.iff | application/x-iff | .ig4 | application/x-g4 |
.igs | application/x-igs | .iii | application/x-iphone |
.img | application/x-img | .ins | application/x-internet-signup |
.isp | application/x-internet-signup | .IVF | video/x-ivf |
.java | java/* | .jfif | image/jpeg |
.jpe | image/jpeg | .jpe | application/x-jpe |
.jpeg | image/jpeg | .jpg | image/jpeg |
.jpg | application/x-jpg | .js | application/x-javascript |
.jsp | text/html | .la1 | audio/x-liquid-file |
.lar | application/x-laplayer-reg | .latex | application/x-latex |
.lavs | audio/x-liquid-secure | .lbm | application/x-lbm |
.lmsff | audio/x-la-lms | .ls | application/x-javascript |
.ltr | application/x-ltr | .m1v | video/x-mpeg |
.m2v | video/x-mpeg | .m3u | audio/mpegurl |
.m4e | video/mpeg4 | .mac | application/x-mac |
.man | application/x-troff-man | .math | text/xml |
.mdb | application/msaccess | .mdb | application/x-mdb |
.mfp | application/x-shockwave-flash | .mht | message/rfc822 |
.mhtml | message/rfc822 | .mi | application/x-mi |
.mid | audio/mid | .midi | audio/mid |
.mil | application/x-mil | .mml | text/xml |
.mnd | audio/x-musicnet-download | .mns | audio/x-musicnet-stream |
.mocha | application/x-javascript | .movie | video/x-sgi-movie |
.mp1 | audio/mp1 | .mp2 | audio/mp2 |
.mp2v | video/mpeg | .mp3 | audio/mp3 |
.mp4 | video/mpeg4 | .mpa | video/x-mpg |
.mpd | application/vnd.ms-project | .mpe | video/x-mpeg |
.mpeg | video/mpg | .mpg | video/mpg |
.mpga | audio/rn-mpeg | .mpp | application/vnd.ms-project |
.mps | video/x-mpeg | .mpt | application/vnd.ms-project |
.mpv | video/mpg | .mpv2 | video/mpeg |
.mpw | application/vnd.ms-project | .mpx | application/vnd.ms-project |
.mtx | text/xml | .mxp | application/x-mmxp |
.net | image/pnetvue | .nrf | application/x-nrf |
.nws | message/rfc822 | .odc | text/x-ms-odc |
.out | application/x-out | .p10 | application/pkcs10 |
.p12 | application/x-pkcs12 | .p7b | application/x-pkcs7-certificates |
.p7c | application/pkcs7-mime | .p7m | application/pkcs7-mime |
.p7r | application/x-pkcs7-certreqresp | .p7s | application/pkcs7-signature |
.pc5 | application/x-pc5 | .pci | application/x-pci |
.pcl | application/x-pcl | .pcx | application/x-pcx |
application/pdf | application/pdf | ||
.pdx | application/vnd.adobe.pdx | .pfx | application/x-pkcs12 |
.pgl | application/x-pgl | .pic | application/x-pic |
.pko | application/vnd.ms-pki.pko | .pl | application/x-perl |
.plg | text/html | .pls | audio/scpls |
.plt | application/x-plt | .png | image/png |
.png | application/x-png | .pot | application/vnd.ms-powerpoint |
.ppa | application/vnd.ms-powerpoint | .ppm | application/x-ppm |
.pps | application/vnd.ms-powerpoint | .ppt | application/vnd.ms-powerpoint |
.ppt | application/x-ppt | .pr | application/x-pr |
.prf | application/pics-rules | .prn | application/x-prn |
.prt | application/x-prt | .ps | application/x-ps |
.ps | application/postscript | .ptn | application/x-ptn |
.pwz | application/vnd.ms-powerpoint | .r3t | text/vnd.rn-realtext3d |
.ra | audio/vnd.rn-realaudio | .ram | audio/x-pn-realaudio |
.ras | application/x-ras | .rat | application/rat-file |
.rdf | text/xml | .rec | application/vnd.rn-recording |
.red | application/x-red | .rgb | application/x-rgb |
.rjs | application/vnd.rn-realsystem-rjs | .rjt | application/vnd.rn-realsystem-rjt |
.rlc | application/x-rlc | .rle | application/x-rle |
.rm | application/vnd.rn-realmedia | .rmf | application/vnd.adobe.rmf |
.rmi | audio/mid | .rmj | application/vnd.rn-realsystem-rmj |
.rmm | audio/x-pn-realaudio | .rmp | application/vnd.rn-rn_music_package |
.rms | application/vnd.rn-realmedia-secure | .rmvb | application/vnd.rn-realmedia-vbr |
.rmx | application/vnd.rn-realsystem-rmx | .rnx | application/vnd.rn-realplayer |
.rp | image/vnd.rn-realpix | .rpm | audio/x-pn-realaudio-plugin |
.rsml | application/vnd.rn-rsml | .rt | text/vnd.rn-realtext |
.rtf | application/msword | .rtf | application/x-rtf |
.rv | video/vnd.rn-realvideo | .sam | application/x-sam |
.sat | application/x-sat | .sdp | application/sdp |
.sdw | application/x-sdw | .sit | application/x-stuffit |
.slb | application/x-slb | .sld | application/x-sld |
.slk | drawing/x-slk | .smi | application/smil |
.smil | application/smil | .smk | application/x-smk |
.snd | audio/basic | .sol | text/plain |
.sor | text/plain | .spc | application/x-pkcs7-certificates |
.spl | application/futuresplash | .spp | text/xml |
.ssm | application/streamingmedia | .sst | application/vnd.ms-pki.certstore |
.stl | application/vnd.ms-pki.stl | .stm | text/html |
.sty | application/x-sty | .svg | text/xml |
.swf | application/x-shockwave-flash | .tdf | application/x-tdf |
.tg4 | application/x-tg4 | .tga | application/x-tga |
.tif | image/tiff | .tif | application/x-tif |
.tiff | image/tiff | .tld | text/xml |
.top | drawing/x-top | .torrent | application/x-bittorrent |
.tsd | text/xml | .txt | text/plain |
.uin | application/x-icq | .uls | text/iuls |
.vcf | text/x-vcard | .vda | application/x-vda |
.vdx | application/vnd.visio | .vml | text/xml |
.vpg | application/x-vpeg005 | .vsd | application/vnd.visio |
.vsd | application/x-vsd | .vss | application/vnd.visio |
.vst | application/vnd.visio | .vst | application/x-vst |
.vsw | application/vnd.visio | .vsx | application/vnd.visio |
.vtx | application/vnd.visio | .vxml | text/xml |
.wav | audio/wav | .wax | audio/x-ms-wax |
.wb1 | application/x-wb1 | .wb2 | application/x-wb2 |
.wb3 | application/x-wb3 | .wbmp | image/vnd.wap.wbmp |
.wiz | application/msword | .wk3 | application/x-wk3 |
.wk4 | application/x-wk4 | .wkq | application/x-wkq |
.wks | application/x-wks | .wm | video/x-ms-wm |
.wma | audio/x-ms-wma | .wmd | application/x-ms-wmd |
.wmf | application/x-wmf | .wml | text/vnd.wap.wml |
.wmv | video/x-ms-wmv | .wmx | video/x-ms-wmx |
.wmz | application/x-ms-wmz | .wp6 | application/x-wp6 |
.wpd | application/x-wpd | .wpg | application/x-wpg |
.wpl | application/vnd.ms-wpl | .wq1 | application/x-wq1 |
.wr1 | application/x-wr1 | .wri | application/x-wri |
.wrk | application/x-wrk | .ws | application/x-ws |
.ws2 | application/x-ws | .wsc | text/scriptlet |
.wsdl | text/xml | .wvx | video/x-ms-wvx |
.xdp | application/vnd.adobe.xdp | .xdr | text/xml |
.xfd | application/vnd.adobe.xfd | .xfdf | application/vnd.adobe.xfdf |
.xhtml | text/html | .xls | application/vnd.ms-excel |
.xls | application/x-xls | .xlw | application/x-xlw |
.xml | text/xml | .xpl | audio/scpls |
.xq | text/xml | .xql | text/xml |
.xquery | text/xml | .xsd | text/xml |
.xsl | text/xml | .xslt | text/xml |
.xwd | application/x-xwd | .x_b | application/x-x_b |
.sis | application/vnd.symbian.install | .sisx | application/vnd.symbian.install |
.x_t | application/x-x_t | .ipa | application/vnd.iphone |
.apk | application/vnd.android.package-archive | .xap | application/x-silverlight-app |
OpenInterpreter是一个可以让语言模型在本地环境中运行代码的开源项目,它提供了一个类似ChatGPT的自然语言界面,用户可以用它完成很多实用的任务1。
例如,处理文件、控制浏览器、分析数据等。此外,OpenInterpreter还能通过执行Python代码来解决数学问题,它可以让GPT-4在本地环境(或在Google Colab)中执行Python代码,功能非常强大。
它是一个让你可以在本地环境中运行比chatgpt解释器更强大的开源版本。你可以通过一个类似于ChatGPT的界面,用自然语言与你的电脑进行交流,执行各种各样的任务。
你可以在计算机上提供自然语言界面来控制和编写代码,创建和编辑照片、视频、PDF和其他文件。你还可以控制Web浏览器进行网络搜索,并使用代码解释器搜索Web上不同的区域,以实现并提供完成任务所必需的链接。你还可以绘制、清理和分析大型数据集等等。接下来我将展示如何访问Open CodeInterpreter,你只需要在您的桌面上安装它。
Open Interpreter 是完全开源的,它可以运行gpt4以及许多其他模型,可以运行来自Python、JavaScript、Shell等不同语言的代码。你只需要通过终端与Open Interpreter进行类似于chatgpt的界面交互,并且基本上可以让你处理不同类型的任务。
首先我们将看看如何在本地安装它。首先,您需要确保已安装Git。其次,您需要安装Python,这将用于实现我们希望代码解释器使用的代码语言。
克隆完成后,进入open interpreter文件夹,即open interpreter。在这里输入pip install open interpreter,它将开始安装此软件包的要求。这可能需要几分钟,安装完成后,直接执行interpreter就可以运行了。
用推荐的gpt4,也可以使用免费的code llama。如果您不想使用gpt4,只需按回车即可。但在这种情况下,您可以在此处上传您的API密钥。
你可以与AI一起工作,创建和生成不同类型的应用程序、不同类型的任务等等。可以做的事情有很多,因为Open Interpreter实际上能够做很多不同类型的事情,您可以转换PDF文件、编辑某些内容、搜索Web,它基本上是一个助手,可以帮助您开发不同类型的任务。我强烈建议您尝试并在本地主机上安装使用一下,绝对超出你的想象。
与ChatGPT的代码解释器进行比较
现在,你可能会想知道为什么要使用Open Interpreter,而不是ChatGPT的代码解释器。首先,ChatGPT的代码解释器是一个付费计划,你需要拥有GPT 4的月度订阅,需要支付约20美元。其次,chatgpt代码解释器无法访问互联网,同时它还限制了一组预安装的软件包,并且最多可以上传100MB的内容。它还需要120秒的运行时间限制。这就是为什么我们使用Open Interpreter的原因,因为它打开了更多的可能性,可以利用此代码解释器来实现许多不同的事情,而不受互联网访问的限制,不受预安装的软件包的限制,可以上传最大数量的内容。当环境终止时,状态不会被清除,而是保留,并且具有存储在此应用程序中的历史记录,可以与之前的项目或之前的工作进行聊天和交互。与单纯的chatgpt代码解释器相比,这是一种更棒的方式,可以使用Open Interpreter与gpt4以及其他类型的模型一起使用。
PAM(Pluggable Authentication Modules)是Unix和类Unix系统提供的一个通用的认证模块框架,可以支持多种认证方式,如本地用户数据库、LDAP、NIS、RADIUS等。
在Dante中,PAM配置用于进行用户身份验证。要配置Dante的PAM,您需要编辑Dante的配置文件,例如"dante.conf",并添加以下参数:
- "method: pam":指定使用PAM进行身份验证的方法。
- "login_user":指定用于身份验证的登录用户。
- "login_path":指定登录脚本的路径。
- 配置文件如下,以下配置是需要主机上生成的用户名,密码才可以连接的方案。
- 开启防火墙:ufw allow 1080。
注意:
- user.privileged: root #必须是root,默认是proxy,无法验证用户
- external: eth0 # 有些主机网卡名称不是这个,应该用ifconfig查看网卡名称
- socksmethod: username # 代表着验证用户密码
- curl -v -x socks5://用户名:密码@服务器ip:端口 http://www.google.com/ 用这个命令后不显示reject等错误信息就说明服务器配置OK
logoutput: syslog
user.privileged: root
user.unprivileged: nobody
# The listening network interface or address.
internal: eth0 port=1080
# The proxying network interface or address.
external: eth0
# socks-rules determine what is proxied through the external interface.
socksmethod: username
# client-rules determine who can connect to the internal interface.
clientmethod: none
client pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
}
socks pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
}