for i in table.get_children()[0].get_children()[0].get_symbols(): describe_symbol(i)
Symbol: bb is referenced is local is assigned Symbol: aa is referenced is free Symbol: cc is referenced isglobal
free
variable:如果变量在一个代码块内使用(在代码内被绑定),但是并没有在其中定义,那么这个变量是自由变量。顺便提一句,使用了自由变量的函数就是闭包(closure)。
global variable:如果变量代码在模块级别被绑定,这个变量是全局变量。
local variable:如果变量在代码块内被绑定,这个变量是局部变量。
In Scala there is a rather arbitrary distinction between functions
defined as methods, which are introduced with the
def keyword, and function values, which are the first-class
objects we can pass to other functions, put in collections, and so
on.
// error: // val covariant_b1: covariant1[Bird] = new covariant1[Animal] val variant_b2: variant1[Bird] = new variant1[Chicken] │ │ │ │ └────────────┘ └───────────────┘ ▲ │ └───────────────────────┘ to supper class
classcontravariant2[-A]
val contravariant_b3: contravariant2[Bird] = new contravariant2[Animal] // error: // val contravariant_b4: contravariant2[Bird] = new contravariant2[Chicken]
┌────────────────────────┐ │ contravariant position │ └────────────────────────┘ ▲ ┌──────────────────┘ │ def foo(a: A): B │ └────────────┐ ▼ ┌────────────────────┐ │ covariant position │ └────────────────────┘
对于高阶函数,从外层向内分析。类型最终是什么 position
由分析过程中,各个类型的“累加”得到。就函数 foo
而言,A => B 是在 contravariant position;就函数
f 而言, A 是在 contravariant
position,B 是在 covariant position。因此,最终
A 是在 covariant position(可以理解为两个 negative position
合并,负负得正),而 B 是在 contravariant position。
这个定义将会导致编译错误,Error:... covariant type A occurs in contravariant position in type。orElse
函数接受参数Option[A],这个位置(contravariant
position)是只能将 A 转换为 A
的子类型的地方。但是类型 A 是 covariant
的,也就是说在所有上下文中,都可安全的把 A 转换为
A 父类。这里出现了冲突。
对于 orElse,解决方式是不使用
A,使用边界限定类型为 A 的父类。
1 2 3 4
deforElse[B >: A](o: Option[B]): Option[B] = thismatch { caseNone => ob case _ => this }
那为什么不,
1 2 3 4 5
// 1. deforElse[B <: A](o: Option[B]): Option[B]
// 2. deforElse[B](o: Option[B]): Option[B]
orElse 返回值可能的类型为 Option[B] 或
Option[A], * 对于1,B 是 A
的子类,Option[B] 是 Option[A] 的子类,当返回
this 时,类型为
Option[A],这里无法从父类转换到子类。 * 对于2,当返回
this 时,类型为 Option[A],和
Option[B] 完全无关,类型不匹配。
ORDER BY x: guarantees global ordering, but does this by pushing
all data through just one reducer. This is basically unacceptable for
large datasets. You end up one sorted file as output.
SORT BY x: orders data at each of N reducers, but each reducer
can receive overlapping ranges of data. You end up with N or more sorted
files with overlapping ranges.
DISTRIBUTE BY x: ensures each of N reducers gets non-overlapping
ranges of x, but doesn't sort the output of each reducer. You end up
with N or unsorted files with non-overlapping ranges.
CLUSTER BY x: ensures each of N reducers gets non-overlapping
ranges, then sorts by those ranges at the reducers. This gives you
global ordering, and is the same as doing (DISTRIBUTE BY x and SORT BY
x). You end up with N or more sorted files with non-overlapping
ranges.
select case when t.idfa != '' and t.idfa != null then t.idfa end from (select 'B5BF3011-A8A0-46A2-B8C3-0A1976FDD4BE' as idfa) as t; select case when t.idfa != '' and t.idfa != NULL then t.idfa end from (select 'B5BF3011-A8A0-46A2-B8C3-0A1976FDD4BE' as idfa) as t; select case when t.idfamd5 != null then '1' else '2' end from (select '\N' as idfamd5) as t; select case when t.idfamd5 != null then '1' else '2' end from (select NULL as idfamd5) as t;