2020年5月

sql server 无限递归查询树的下级、上级数据


表数据

select id,dept_nam,pid from dept

2020-05-28T06:34:56.png


查询树状结构某节点(75)的下级所有节点

with 
    dept_parent(id,dept_nam,pid) 
as
( 
  select 
    id,dept_nam,pid 
  from 
    dept 
  where 
    id = 75
  
  union all
  
  select 
    a.id,a.dept_nam,a.pid 
  from 
    dept a 
  inner join 
    dept_parent b
  on 
    a.pid=b.id  
)    
select * from dept_parent;

2020-05-28T06:37:38.png


查询树状结构某节点(77)的上级所有节点

with 
    dept_parent_s(id,dept_nam,pid) 
as
( 
  select 
    id,dept_nam,pid 
  from 
    dept 
  where 
    id = 77
  
  union all
  
  select 
    a.id,a.dept_nam,a.pid 
  from 
    dept a 
  inner join 
    dept_parent_s b
  on 
    a.id=b.pid
)    
select * from dept_parent_s

2020-05-28T06:39:13.png


golang中的多态



package main

import (
    "fmt"

)
//通知行为的接口
type notifier interface{
    notify()
}

//自定义的用户类型
type user struct{
    name string
    email string 
}
//notify是用指针接收者实现的方法
func (u *user ) notify(){
    fmt.Println("用户:",u)
}


//自定义的管理员类型
type admin struct{
    name string
    email string 
}
//notify是用指针接收者实现的方法
func (u *admin ) notify(){
    fmt.Println("管理员:",u)
}


func main(){
    user := user{"lp","344085057@qq.com"}
    sendNotification(&user)

    admin := admin{"admin","344085057@qq.com"}
    sendNotification(&admin)
}
//sendNotification 接受一个实现了notifier接口的值
func sendNotification(n notifier){
    n.notify()
}
运行结果

用户: &{lp 344085057@qq.com}
管理员: &{admin 344085057@qq.com}


golang接口中方法集的运行机制



package main

import(
    "fmt"
)
//通知行为的接口
type notifier interface{
    notify()
}
//自定义的用户类型
type user struct{
    name string
    email string 
}
//notify是用指针接收者实现的方法
func (u *user ) notify(){
    fmt.Println(u)
}

func main(){
    u:= user{"lp","344085057@qq.com"}
    sendNotification(u)
}
//sendNotification 接受一个实现了notifier接口的值
func sendNotification(n notifier){
    n.notify()
}
运行结果:

cannot use u (type user) as type notifier in argument to sendNotification:
user does not implement notifier (notify method has pointer receiver)

翻译

无法在sendNotification的参数中使用u(type user)类型:
user未实现sendNotification(notify方法具有指针接收器)

原因

//因为这里 只有指向user的指针才能够实现对应的接口。
sendNotification(u)

//正确的调用姿势
sendNotification(&u)

让我们来了解go语言规范里定义的方法集的规则:

从值的角度看这些规则:

Values           Methods Receivers
————————————————————————————
T                      (t T)
*T                    (t T) or (t *T)
描述:

T类型的值的方法集只包含值接收者申明的方法。
*T(T类型的指针) 类型的指针的方法集即包含值接收者申明的方法,也包含指针接收者声明的方法。

从接收者类型的角度来看这些规则:

 Methods Receivers       Values          
————————————————————————————
(t T)                                          T
(t T) or (t *T)                       *T
描述:

如果使用指针接收者来实现一个接口,那么只有指向那个类型的指针才能够实现对应的接口。
如果使用值接收者来实现一个接口,那么那个类型的值和指针都能够实现对应的接口


golang之并发同步sync.WaitGroup


本例子并行地访问URL,使用 WaitGroup 进行阻塞,直到所有的取回操作完成。

package main

import (
    "fmt"
    "net/http"
    "sync"
)

var wg sync.WaitGroup

func main() {
    var wg sync.WaitGroup
    var urls = []string{
        "https://www.52bd.net/",
        "https://www.baidu.com/",
        "https://go-zh.org/",
    }
    for _, url := range urls {
        // Increment the WaitGroup counter.
        // 递增 WaitGroup 计数器。
        wg.Add(1)
        // Launch a goroutine to fetch the URL.
        // 启动一个Go程来取回URL。
        go func(url string) {
            defer wg.Done()

            // Decrement the counter when the goroutine completes.
            // Fetch the URL.
            // 请求URL
            resp, _ := http.Get(url)
            fmt.Println(resp.Status)//输出请求状态

        }(url)
    }
    // Wait for all HTTP fetches to complete.
    // 等待所有的HTTP取回操作完成。
    wg.Wait()
}

func (wg *WaitGroup) Add(delta int)

Add 添加 delta,对于 WaitGroup 的 counter 来说,它可能为负数。 若 counter 变为零,在 Wait() 被释放后所有Go程就会阻塞。 若 counter 变为负数,Add 就会引发Panic。

注意,当 counter 为零时,用正整数的 delta 调用它必须发生在调用 Wait 之前。 用负整数的 delta 调用它,或在 counter 大于零时开始用正整数的 delta 调用它, 那么它可以在任何时候发生。 一般来说,这意味着对 Add 的调用应当在该语句创建Go程,或等待其它事件之前执行。 具体见 WaitGroup 的示例。

func (wg *WaitGroup) Done()

Done 递减 WaitGroup 的 counter。

func (wg *WaitGroup) Wait()

Wait 阻塞 WaitGroup 直到其 counter 为零。