伊莉討論區

標題: type annotation 是什麼? [打印本頁]

作者: CodeMonk    時間: 2016-4-29 02:09 PM     標題: type annotation 是什麼?

本帖最後由 CodeMonk 於 2016-4-29 02:10 PM 編輯

先說說我對type的了解,不然可能有些大前提就是錯的,所謂的type(型別),就是指記憶體實際儲存的型態或是方法,哪一個bits代表什麼意思,由型別決定,比較有問題的事變數的型別,一般變數型別有兩種實作方法,一個是動態、一個是靜態,所謂的動態,是像些腳本語言一樣,只要你賦值,他就會以你所賦的值為變數的型別;而靜態通常要先宣告,說變數是什麼就是什麼,但可能會提供一些轉型的辦法。


回到我的問題,type annotation是什麼,聽起來好像是型別註釋,我是在一本教julia語言的書上看到,但看完書也不能理解,內容擷取(我把一小節整個擷取下來):『
Types


Julia’s type system is unique. Julia behaves as a dynamically-typed language (such as
Python for instance) most of the time. This means that a variable bound to an integer at
one point might later be bound to a string. For example, consider the following:
julia> x = 10
10
julia> x = "hello"
"hello"

However, one can, optionally, add type information to a variable. This causes the variable
to only accept values that match that specific type. This is done through a type annotation.
For instance, declaring x::ASCIIString implies that only strings can be bound to x; in
general, it looks like var::TypeName. These are used most often to qualify the arguments a
function can take. The extra type information is useful for documenting the code, and
often allows the JIT compiler to generate better optimized native code. It also allows the
development environments to give more support, and code tools such as a linter that can
check your code for possible wrong type use.
Here is an example: a function with the calc_position name defined as the function
calc_position(time::Float64), indicates that this function takes one argument named
time of the type Float64.
Julia uses the same syntax for type assertions that are used to check whether a variable or
an expression has a specific type. Writing (expr)::TypeName raises an error if expr is not
of the required type. For instance, consider the following:
julia> (2+3)::ASCIIString
ERROR: type: typeassert: expected ASCIIString, got Int64
Notice that the type comes after the variable name, unlike in most other languages. In
general, the type of a variable can change in Julia, but this is detrimental to performance.
For utmost performance, you need to write type-stable code. Code is type-stable if the
type of every variable does not vary over time. Carefully thinking in terms of the types of
variables is useful in avoiding performance bottlenecks. Adding type annotations to
variables updated in the inner loop of a critical region of code can lead to drastic
improvements in the performance by helping the JIT compiler remove some type
checking. To see an excellent example where this is important, read the article available at
http://www.johnmyleswhite.com/notebook/2013/12/06/writing-type-stable-code-in-julia/.
A lot of types exist, in fact, a whole type hierarchy is built in in Julia. If you don’t specify
the type of a function argument, it has the type Any, which is effectively the root or parent
of all types. Every object is at least of the universal type Any. At the other end of the
spectrum, there is type None that has no values. No object can have this type, but it is a
subtype of every other type. While running the code, Julia will infer the type of the
parameters passed in a function, and with this information, it will generate optimal
machine code.




You can define your own custom types as well, for instance, a Person type. By
convention, the names of types begin with a capital letter, and if necessary, the word
separation is shown with CamelCase, such as BigFloat or AbstractArray.
If x is a variable, then typeof(x) gives its type, and isa(x, T) tests whether x is of type
T. For example, isa("ABC", String) returns true, and isa(1, Bool) returns false.
Everything in Julia has a type, including types themselves, which are of type DataType:
typeof(Int64) returns DataType. Conversion of a variable var to a type Type1 can be
done using the type name (lower-cased) as a function type1(var), for example,
int64(3.14) returns 3.
However, this raises an error if type conversion is impossible as follows:
julia> int64("hello")
ERROR: invalid base 10 digit 'h' in "hello"






作者: chevylin0802    時間: 2016-5-3 10:48 AM

本帖最後由 chevylin0802 於 2016-5-3 10:56 AM 編輯

基本上只有像是腳本語言才有你講的Type annotation這種東西
最常見的比如javascripts

事實上我們並不會把它當成是動態型別來看待
比較好的看法是把所宣告的變數當成是可動態重複宣告的變數
當它重複被宣告成另外型別的時候
等於原先的變數的生存週期已經結束
因此頂多只是變數名稱同名
但事實上對於腳本語言JIT Compiler而言已經不是同一個變數(原先的變數已經在結束的時候不存在)
包括配置給原先定義的變數所在的記憶體位址
而且重新定義型別的時候
會重新再根據型別重新配置新的記憶體位址
因此你必需要把它視為兩者其實根本就是不同的變數
只是變數名稱同名而已






作者: CodeMonk    時間: 2016-5-9 01:56 AM

chevylin0802 發表於 2016-5-3 10:48 AM
基本上只有像是腳本語言才有你講的Type annotation這種東西
最常見的比如javascripts

了解,所以我可以想像每一次賦值,都是從新宣告(有就是說變數的記憶體位置和記憶體大小是會隨每一次賦值改變),然後它的scope就是兩個同名變數的總和!
可以把它想成同名變數,但感結不出來有什麼差別!還有Type annotation可以把型別固定,也就是說某一種變數名子裡的內容只能被某以種特定型別賦值,使用方法沒有什麼問題,但實在不能理解把型別固定有什麼意義(用在哪裡?)。

作者: chevylin0802    時間: 2016-5-9 07:06 AM

CodeMonk 發表於 2016-5-9 01:56 AM
了解,所以我可以想像每一次賦值,都是從新宣告(有就是說變數的記憶體位置和記憶體大小是會隨每一次賦值 ...

可以說是為了程式的可讀性吧!

日益龐大的原生碼
也產生了不少的後遺症
其一就是程式碼的可讀性問題
變數也好函式也好
變數名稱越做越長
函式名稱也是越做越長
尤其是像C語言並不具備物件特徵
而像Javascripts之類的雖然也具備物件特徵
卻不是完整而全部都是物件

當變數名超過五個字母以上的時候
當函式名稱超過十個字母以上的時候
可讀性就會開始變差

也因此Type annotation開始意味著另一種變數命名的簡化
但是這種簡化只是在變數數量上降低
並不是真正提高可讀性






歡迎光臨 伊莉討論區 (http://a401.file-static.com/) Powered by Discuz!