In part 3 of building your own email server on Ubuntu tutorial series, we implemented SPF and DKIM records to improve email deliverability. In this pa…
Part 3: How to Set up SPF and DKIM with Postfix on Ubuntu Server
After completing part 1 and part 2, we have a working Postfix SMTP server and Dovecot IMAP server. We can send and receive email using a desktop email…
Part 2: How to Install Dovecot IMAP server on Ubuntu and Enable TLS Encryption
This is part 2 of building your own secure email server on Ubuntu tutorial series. In part 1, we showed you how to set up a basic Postfix SMTP server,…
Build Your Own Email Server on Ubuntu: Basic Postfix Setup
Why build your own email server? Have you heard that Hillary Clinton uses her private email server? Hillary used it for her evil purposes. But buildin…
Go语言开发-过程式编程-自定义函数-闭包
5.6.3.闭包 闭包是指可以“捕获”同一作用域中所有常量和变量的一种函数,这意味着闭包在被调用时能够访问这些常量和变量,而不管闭包在何处被调用。这些常量或变量是否超出了作用域并不重要,只要闭包还在引用它们,它们就会一直存活着,以便闭包能够使用它们。 在Go语言中,所有的匿名函数(Go语言规范称之为…
Go语言开发-过程式编程-自定义函数-init()和main()函数
5.6.2. init()和main()函数 Go语言有两个特殊作用的保留函数:init()(在所有包中)和main()(只在main包中),这两个函数必须始终定义且不接受任何参数,也没有任何返回值。一个包中可以有多个init()函数。 Go语言会自动调用所有包中的init()函数和main包中的m…
Go语言开发-过程式编程-自定义函数-可选参数函数
5.6.1.3. 可选参数函数 Go语言不支持直接创建具有多个不同类型的可选参数函数。但是,我们可以使用特殊的函数struct并依赖Go语言可以将所有的值都初始化为其类型的零值来实现。 假如我们有一个用于处理某些自定义数据的函数,其中默认是处理所有的数据,但在某些情况下,我们希望能够指定要处理的第一…
Go语言开发-过程式编程-自定义函数-可变参数函数
5.6.1.2. 可变参数函数 可变参数函数是其最后一个(或仅有的一个)参数可以接受零个或多个参数的函数。这些函数是通过在最后一个或仅有的一个参数类型之前放置省略号(…)来表示的,在函数内部,该参数的类型是给定类型的切片。例如,如果有一个函数Join(xs …string) …
Go语言开发-过程式编程-自定义函数-函数调用作为函数参数
5.6.1.1. 函数调用作为函数参数 如果一个函数或方法接受一个或多个参数,我们当然可以传入相应的参数来调用它。此外,我们也可以传入另一个函数或方法来调用该函数,但前提是另一个函数的返回值和类型与要调用的函数参数一致。 下面的函数接受三角形三个边的长度作为参数(三个int类型),并使用Heron公…
Go语言开发-过程式编程-自定义函数-函数参数
5.6.1. 函数参数 我们已经演示了许多Go语言自定义函数的例子,这些函数都接受指定类型的固定数量的参数。我们可以通过使用interface{}类型来创建接受任意类型参数的函数。通过使用interface{},不管是自定义接口还是Go语言标准库中的,我们可以创建具有一组特定方法的接受任意类型参数的…
Go语言开发-过程式编程-自定义函数
5.6. 自定义函数 函数是过程式编程的基石,Go语言为它们提供了一流的支持。Go语言中的方法与函数非常相似,因此本节既适用于过程式编程,也适用于面向对象的编程。 下面是函数定义的基本语法:
1 2 3 4 5 6 | func functionName(optionalParameters) optionalReturnType { body } func functionName(optionalParameters) optionalReturnValues { body } |
一个函数可以接受零个或多个参数。如果没有参…
Go语言开发-过程式编程-Panic和Recover
5.5.1. Panic和Recover Go语言通过其内置的panic()和recover()函数提供异常处理机制。这两个函数提供了可以像其他语言(如C++、Java和Python)一样的通用异常处理机制,但是早Go语言中这样做不是一种好的编程风格。 Go区分错误和异常,错误是指可能出现错误但是程…
Go语言开发-过程式编程-Defer,Panic和Recover
5.5. Defer,Panic,和Recover defer语句用于将函数或方法(或匿名函数)延迟到函数结束或方法返回之前但要在返回值(如果有的话)计算之后执行。这也使得在defer语句块中修改函数的返回值成为可能(例如,使用运算符=赋值)。如果在一个函数或方法中使用了多个defer语句,则按照L…
Go语言开发-过程式编程-通信和并发语句-Select语句
5.4.1. Select语句 Go语言的select语句语法如下:
1 2 3 4 5 6 | select { case sendOrReceive1: block1 ... case sendOrReceiveN: blockN default: blockD } |
在select语句中Go语言会按顺序评估每一个发送和接收语句,如果任何语句可以继续进行(即没有被阻塞),则任意选择这些语句中一个来执行;如果没有可以继续执行的语句(…
Go语言开发-过程式编程-通信和并发语句
5.4. 通信和并发语句 Go语言的通信和并发功能将在第7章详细讲解,但是这里为了过程式编程的完整性,我们会简要介绍其基本语法。 goroutine是程序中与其它goroutine相互独立而又并发执行的函数或方法调用。每个Go程序至少有一个goroutine,主goroutine 在main包中的m…