歡迎加入QQ討論群258996829
Swift 頭像
蘋果5袋
5
Swift

對蘋果“五仁”編程語言Swift的簡單分析

發(fā)布時間:2014-07-05 18:27  回復(fù):0  查看:3410   最后回復(fù):2014-07-05 18:27  

在CSDN上看到的文章。轉(zhuǎn)給大家。


蘋果在昨天的WWDC上,發(fā)布了新的編程語言Swift。這兩天開發(fā)社區(qū)都在討論這個語言,從語言的特性上大家發(fā)現(xiàn)了好多語言的影子,這樣的情況可以說是集大成,也可以說是“五仁”。每個人看問題的角度都不同,下面從個人的角度來看看這門語言涉及到的工具鏈及其對越獄開發(fā)的影響。

由于剛剛發(fā)布,針對相關(guān)工具的介紹幾乎沒有,那我們就從xcode中尋找。在shell中執(zhí)行:

find /Applications/Xcode6-Beta.app/Contents/ -name "*swift*" 
可以找到swift相關(guān)的文件,簡單過濾后,如下的文件比較重要:


/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift
/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-demangle
/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-ide-test
/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-stdlib-tool
/Applications/Xcode6-Beta.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/repl_swift
/Applications/Xcode6-Beta.app/Contents//Developer/Toolchains/XcodeDefault.xctoolchain/usr/share/man/man1/swift.1
從找到的文件中我們可以看到包含 man 手冊文件,我們首先看看手冊的內(nèi)容:


swift(1)                                   Swift Documentation                                  swift(1)

NAME
       swift - <strong>the amazingly new programming language</strong>

SYNOPSIS
       swift [-emit-object|-emit-assembly|-emit-library|-i]
         [-help]
         -o output-file
         input-filenames

       The full list of supported options is available via "swift -help".

DESCRIPTION
       Swift is a new, high performance systems programming language.  It has a clean and modern syntax,
       and offers seamless access to existing C and Objective-C code and frameworks, and is memory safe
       (by default).

       Although inspired by Objective-C and many other languages, Swift is not itself a C-derived
       language. As a complete and independent language, Swift packages core features like flow control,
       data structures, and functions, with high-level constructs like objects, protocols, closures, and
       generics.  Swift embraces modules, eliminating the need for headers and the code duplication they
       entail.

                                               2014-05-17                                       swift(1)
從手冊中可以得到的信息也非常有限,但是看到參數(shù):-help,我們看看幫助會輸出什么:


OVERVIEW: Swift compiler

USAGE: swift [options] <inputs>

MODES:
  -dump-ast        Parse and type-check input file(s) and dump AST(s)
  -dump-parse      Parse input file(s) and dump AST(s)
  -emit-assembly   Emit assembly file(s) (-S)
  -emit-bc         Emit LLVM BC file(s)
  -emit-executable Emit a linked executable
  -emit-ir         Emit LLVM IR file(s)
  -emit-library    Emit a linked library
  -emit-object     Emit object file(s) (-c)
  -emit-silgen     Emit raw SIL file(s)
  -emit-sil        Emit canonical SIL file(s)
  -integrated-repl Integrated REPL mode
  -i               Immediate mode
  -lldb-repl       LLDB-enhanced REPL mode
  -parse           Parse input file(s)
  -print-ast       Parse and type-check input file(s) and pretty print AST(s)
  -repl            REPL mode

OPTIONS:
  -application-extension  Restrict code to those available for App Extensions
  -arch <arch>            Compile for architecture <arch>
  -assert-config <value>  Specify the assert_configuration replacement. Possible values are Debug, Release, Replacement.
  -D <value>              Specifies one or more build configuration options
  -emit-dependencies      Emit Make-compatible dependencies files
  -emit-module-path <path>
                          Emit an importable module to <path>
  -emit-module            Emit an importable module
  -emit-objc-header-path <path>
                          Emit an Objective-C header file to <path>
  -emit-objc-header       Emit an Objective-C header file
  -framework <value>      Specifies a framework which should be linked against
  -F <value>              Add directory to framework search path
  -g                      Emit debug info
  -help                   Display available options
  -import-underlying-module
                          Implicitly imports the Objective-C half of a module
  -I <value>              Add directory to the import search path
  -j <n>                  Number of commands to execute in parallel
  -L <value>              Add directory to library link search path
  -l<value>               Specifies a library which should be linked against
  -module-cache-path <value>
                          Specifies the Clang module cache path
  -module-link-name <value>
                          Library to link against when using this module
  -module-name <value>    Name of the module to build
  -nostdimport            Don't search the standard library import path for modules
  -output-file-map <path> A file which specifies the location of outputs
  -o <file>               Write output to <file>
  -parse-as-library       Parse the input file(s) as libraries, not scripts
  -parse-sil              Parse the input file as SIL code, not Swift source
  -save-temps             Save intermediate compilation results
  -sdk <sdk>              Compile against <sdk>
  -serialize-diagnostics  Serialize diagnostics in a binary format
  -target-cpu <value>     Generate code for a particular CPU variant
  -target-feature [+-]<feature-name>
                          Generate code with a particular CPU feature enabled or disabled
  -target <value>         Generate code for the given target
  -version                Print version information and exit
  -v                      Show commands to run and use verbose output
  -Xcc <arg>              Pass <arg> to the C/C++/Objective-C compiler
  -Xfrontend <arg>        Pass <arg> to the Swift frontend
  -Xlinker <value>        Specifies an option which should be passed to the linker
  -Xllvm <arg>            Pass <arg> to LLVM.
這么多參數(shù)到底怎么用呢?!我們一起來看看 xcode 是怎么使用的。


打開xcode6新建一個空工程,取名“FuckSwift”:



將工程的Deployment Target改成 5.0,然后編譯,并在設(shè)備上運行。我手上的設(shè)備是iPad2-iOS7.0.4,可以正常運行。為什么可以正常運行?swift相關(guān)的運行時庫怎么處理?我們打開編譯好的app目錄:



可以看到比以前的程序多了一個目錄 Frameworks,內(nèi)容如下:



因此,在iOS8之下的設(shè)備上,程序打包的時候帶上了必要的運行庫。對于iOS8,目前還沒法解開 dyld cache 也就無法知道設(shè)備上是否帶了這些庫,不過應(yīng)該會帶。

 

接上文,我們建立測試工程的目的是為了看看 xcode 如何使用 swift 編譯工具,xcoce編譯時的相關(guān)參數(shù)如下:
/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift 
-target armv7-apple-ios5.0 
-module-name FuckSwift 
-O0 
-sdk /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk 
-g 
-module-cache-path /Users/proteas/Library/Developer/Xcode/DerivedData/ModuleCache 
-I /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Products/Debug-iphoneos 
-F /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Products/Debug-iphoneos 
-parse-as-library 
-c 
-j8 
/Users/proteas/Desktop/FuckSwift/FuckSwift/AppDelegate.swift 
-output-file-map /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/Objects-normal/armv7/FuckSwift-OutputFileMap.json 
-serialize-diagnostics 
-emit-dependencies 
-emit-module 
-emit-module-path /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/Objects-normal/armv7/FuckSwift.swiftmodule 
-Xcc 
-iquote 
-Xcc /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/FuckSwift-generated-files.hmap 
-Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/FuckSwift-own-target-headers.hmap 
-Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/FuckSwift-all-target-headers.hmap 
-Xcc 
-iquote 
-Xcc /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/FuckSwift-project-headers.hmap -Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Products/Debug-iphoneos/include 
-Xcc 
-I/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include 
-Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/DerivedSources/armv7 
-Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/DerivedSources 
-Xcc 
-DDEBUG=1 
-emit-objc-header 
-emit-objc-header-path /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/Objects-normal/armv7/FuckSwift-Swift.h

參數(shù)還是太多,繼續(xù)精簡,把去掉絕對路徑:

swift 	-target armv7-apple-ios5.0
		-module-name FuckSwift
		-O0
		-sdk iPhoneOS8.0.sdk
		-g
		-module-cache-path ModuleCache
		-I Debug-iphoneos 
		-F Debug-iphoneos 
		-parse-as-library 
		-c 
		-j8 
		AppDelegate.swift 
		-output-file-map FuckSwift-OutputFileMap.json 
		-serialize-diagnostics 
		-emit-dependencies 
		-emit-module 
		-emit-module-path FuckSwift.swiftmodule 
		-Xcc -iquote 
		-Xcc FuckSwift-generated-files.hmap 
		-Xcc -IFuckSwift-own-target-headers.hmap 
		-Xcc -IFuckSwift-all-target-headers.hmap 
		-Xcc -iquote 
		-Xcc FuckSwift-project-headers.hmap 
		-Xcc -Iinclude 
		-Xcc -I/usr/include 
		-Xcc -Iarmv7 
		-Xcc -IDerivedSources 
		-Xcc -DDEBUG=1 
		<strong>-emit-objc-header 
		-emit-objc-header-path FuckSwift-Swift.h</strong>

這樣就相對清晰了。這里面的參數(shù)大家可以對照上述的幫助查看,這里我們一起看兩點:

1、Xcc <arg>:Pass <arg> to the C/C++/Objective-C compiler,這里我們可以得到:swift代碼很可能最終被轉(zhuǎn)變成C/C++/Objective-C代碼進行靜態(tài)編譯。


2、會生成FuckSwift-Swift.h頭文件,對比下這個文件與swift文件。

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window!.backgroundColor = UIColor.whiteColor()
        self.window!.makeKeyAndVisible()
        return true
    }
    func applicationWillResignActive(application: UIApplication) {
    }
    func applicationDidEnterBackground(application: UIApplication) {
    }
    func applicationWillEnterForeground(application: UIApplication) {
    }
    func applicationDidBecomeActive(application: UIApplication) {
    }
    func applicationWillTerminate(application: UIApplication) {
    }
}

SWIFT_CLASS("_TtC9FuckSwift11AppDelegate")
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic) UIWindow * window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- (void)applicationWillResignActive:(UIApplication *)application;
- (void)applicationDidEnterBackground:(UIApplication *)application;
- (void)applicationWillEnterForeground:(UIApplication *)application;
- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)applicationWillTerminate:(UIApplication *)application;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

可以看到swift程序是被轉(zhuǎn)換了的,但是是不是轉(zhuǎn)換成了Objective-C程序呢?還需要進一步分析。

打開IDA,加載測試程序的MachO:


我們重點看下函數(shù)窗口:


從函數(shù)名上我們可以得到如下結(jié)論:


1、可以看到函數(shù)名被“改編”了。


2、swift代碼并不是被簡單得編譯成了ObjC代碼


3、swift代碼最終被編譯成了純C代碼,相對于ObjC來說省去了運行時查表進行函數(shù)調(diào)用的開銷,執(zhí)行效率應(yīng)該比ObjC要高。


4、從文檔上看swfit相對于ObjC來說是更加動態(tài)的語言,開發(fā)效率也應(yīng)該比ObjC高


5、對于越獄開發(fā)來說,我們只要像Hook C函數(shù)那樣來Hook swift 函數(shù)就可以了,因此MobileSubstrate還是可以工作的。


6、生成的代碼還是要遵循 ARM 的ABI標(biāo)準(zhǔn)


 

就像C++的名稱改編一樣,改編后的名稱雖然可以手工還原但是太麻煩,最好找到工具來做這一件事。前文,我們在查找swift相關(guān)的文件時看到一個工具:swift-demangle,下面我們就用它來demangle改編后的名稱,看看可以得到什么。

首先,我們切換命令行到xcode6的命令行工具:

sudo xcode-select --switch /Applications/Xcode6-Beta.app/Contents/Developer
然后,我們看看swift-demangle的命令行參數(shù):

USAGE: swift-demangle [options] [mangled name...]

OPTIONS:
  -compact   - Compact mode (only emit the demangled names)
  -expand    - Expand mode (show node structure of the demangling)
  -help      - Display available options (-help-hidden for more)
  -no-sugar  - No sugar mode (disable common language idioms such as ? and [] from the output)
  -tree-only - Tree-only mode (do not show the demangled string)
  -version   - Display the version of this program
從IDA中復(fù)制一個函數(shù)名,如:

__TToFC9FuckSwift11AppDelegate26applicationDidBecomeActivefS0_FCSo13UIApplicationT_
我們執(zhí)行如下命令:

xcrun swift-demangle "__TToFC9FuckSwift11AppDelegate26applicationDidBecomeActivefS0_FCSo13UIApplicationT_"
得到輸出:

_TToFC9FuckSwift11AppDelegate26applicationDidBecomeActivefS0_FCSo13UIApplicationT_ ---> @objc FuckSwift.AppDelegate.applicationDidBecomeActive (FuckSwift.AppDelegate)(ObjectiveC.UIApplication) -> ()

可以看到函數(shù)被還原。

到這里我們停下,看看swift對越獄開發(fā)的影響:


1、目前無法使用class-dump得到ObjC的頭文件。


2、MobileSubstrate應(yīng)該還可以正常工作。


3、可以使用demangle工具還原函數(shù)名,后期這部分工作IDA可能會自動支持。

總之,對越獄開發(fā)的流程會稍微有影響,針對應(yīng)用的越獄開發(fā)還可以存在。


下面我們看看命令行工具swift-ide-test的參數(shù):

OVERVIEW: Swift IDE Test

USAGE: swift-ide-test [options] [input files...]

OPTIONS:
  -D=<string>                              - Build configurations
  -F=<string>                              - add a directory to the framework search path
  -I=<string>                              - add a directory to the import search path
  -annotate-print                          - Annotate AST printing
  -code-completion-diagnostics             - Print compiler diagnostics while doing code completion
  -code-completion-token=<string>          - Code completion token name
  -comments-xml-schema=<string>            - Filename of the RelaxNG schema for documentation comments
  -enable-objc-factory-method-constructors - Implicitly import Objective-C factory methods as initializers
  -enable-objc-implicit-properties         - Implicitly import Objective-C getter/setter pairs as properties
  -explode-pattern-binding-decls           - Separate pattern binding decls into individual var decls
  -fatal-assembler-warnings                - Consider warnings as error
  -fully-qualified-types                   - Print fully qualified types
  -fully-qualified-types-if-ambiguous      - Print types fully-qualified if they would be ambiguous otherwise
  -function-definitions                    - Print function bodies
  -help                                    - Display available options (-help-hidden for more)
  -implicit-objc-with                      - Make the "with" implicit in initializers
  -import-objc-header=<string>             - header to implicitly import
  -module-cache-path=<string>              - Clang module cache path
  -module-print-hidden                     - Print non-exported imported or submodules
  -module-print-skip-overlay               - Skip Swift overlay modules
  -module-print-submodules                 - Recursively print submodules
  -module-to-print=<string>                - Name of the module to print
  -objc-bridge-dictionary                  - Bridge Dictionary<K, V> to NSDictionary
  -prefer-type-repr                        - When printing types, prefer printing TypeReprs
  -print-after-all                         - Print IR after each pass
  -print-before-all                        - Print IR before each pass
  Mode:
    -code-completion                       - Perform code completion
    -repl-code-completion                  - Perform REPL-style code completion
    -syntax-coloring                       - Perform syntax coloring
    -structure                             - Perform document structure annotation
    -annotate                              - Perform semantic annotation
    -test-input-complete                   - Check if input source is complete
    -print-ast-not-typechecked             - Print the non-typechecked AST
    -print-ast-typechecked                 - Print the typechecked AST
    -print-module                          - Print visible declarations in a module
    -print-types                           - Print types of all subexpressions and declarations in the AST
    -print-comments                        - Print documentation comments attached to decls
    -print-module-comments                 - Given a module, print documentation comments attached to decls
    -print-module-imports                  - Recursively print all imports visible from a particular module
    -print-usrs                            - Print USRs for all decls
    -parse-rest                            - Parse a ReST file
  -print-implicit-attrs                    - Print implicit attributes
  -print-regular-comments                  - Print regular comments from clang module headers
  -print-stats                             - Print statistics
  -sdk=<string>                            - path to the SDK to build against
  -skip-private-stdlib-decls               - Don't print declarations that start with '_'
  -skip-unavailable                        - Don't print unavailable declarations
  -source-filename=<string>                - Name of the source file
  -split-objc-selectors                    - Split Objective-C selectors
  -stats                                   - Enable statistics output from program (available with Asserts)
  -synthesize-sugar-on-types               - Always print Array and Optional with sugar
  -target=<string>                         - target triple
  -terminal                                - Use terminal color for source annotations
  -time-passes                             - Time each pass, printing elapsed time for each on exit
  -typecheck                               - Type check the AST
  -version                                 - Display the version of this program


從參數(shù)上看,這很可能是xcode的內(nèi)部工具,用來做代碼完成與檢查的。這里不具體分析,感興趣的兄弟可以自己試試。

 

下面我們繼續(xù)回到 swift 工具上,首先看看parse的輸出,執(zhí)行如下命令:

xcrun swift AppDelegate.swift -dump-parse
得到如下輸出:

(source_file
  (import_decl UIKit')
  (class_decl "AppDelegate" type='<null type>' inherits: <null>, <null>
    (pattern_binding_decl
      (pattern_typed
        (pattern_named 'window')
))
    (var_decl "window" type='<null type>' storage_kind='stored')
    (func_decl "application(_:didFinishLaunchingWithOptions:)" type='<null type>'
      (body_params
        (pattern_typed implicit
          (pattern_named implicit 'self'))
        (pattern_tuple
          (pattern_typed
            (pattern_named 'application')
            (type_ident
              (component id='UIApplication' bind=none)))
          (pattern_typed
            (pattern_named 'launchOptions')
)))
      (result
        (type_ident
          (component id='Bool' bind=none)))
      (brace_stmt
        (sequence_expr type='<null>'
          (unresolved_dot_expr type='<null>' field 'window'
            (declref_expr type='<null>' decl=AppDelegate.(file).AppDelegate.func decl.self@AppDelegate.swift:17:10 specialized=yes))
          (assign_expr
            (**NULL EXPRESSION**)
            (**NULL EXPRESSION**))
          (call_expr type='<null>'
            (unresolved_decl_ref_expr type='<null>' name=UIWindow specialized=no)
            (tuple_expr type='<null>' names=frame
              (unresolved_dot_expr type='<null>' field 'bounds'
                (call_expr type='<null>'
                  (unresolved_dot_expr type='<null>' field 'mainScreen'
                    (unresolved_decl_ref_expr type='<null>' name=UIScreen specialized=no))
                  (tuple_expr type='<null>'))))))
        (sequence_expr type='<null>'
          (unresolved_dot_expr type='<null>' field 'backgroundColor'
            (force_value_expr type='<null>'
              (unresolved_dot_expr type='<null>' field 'window'
                (declref_expr type='<null>' decl=AppDelegate.(file).AppDelegate.func decl.self@AppDelegate.swift:17:10 specialized=yes))))
          (assign_expr
            (**NULL EXPRESSION**)
            (**NULL EXPRESSION**))
          (call_expr type='<null>'
            (unresolved_dot_expr type='<null>' field 'whiteColor'
              (unresolved_decl_ref_expr type='<null>' name=UIColor specialized=no))
            (tuple_expr type='<null>')))
        (call_expr type='<null>'
          (unresolved_dot_expr type='<null>' field 'makeKeyAndVisible'
            (force_value_expr type='<null>'
              (unresolved_dot_expr type='<null>' field 'window'
                (declref_expr type='<null>' decl=AppDelegate.(file).AppDelegate.func decl.self@AppDelegate.swift:17:10 specialized=yes))))
          (tuple_expr type='<null>'))
        (return_stmt
          (unresolved_decl_ref_expr type='<null>' name=true specialized=no))))
    (func_decl "applicationWillResignActive(_:)" type='<null type>'
      (body_params
        (pattern_typed implicit
          (pattern_named implicit 'self'))
        (pattern_tuple
          (pattern_typed
            (pattern_named 'application')
            (type_ident
              (component id='UIApplication' bind=none)))))
      (brace_stmt))
    (func_decl "applicationDidEnterBackground(_:)" type='<null type>'
      (body_params
        (pattern_typed implicit
          (pattern_named implicit 'self'))
        (pattern_tuple
          (pattern_typed
            (pattern_named 'application')
            (type_ident
              (component id='UIApplication' bind=none)))))
      (brace_stmt))
    (func_decl "applicationWillEnterForeground(_:)" type='<null type>'
      (body_params
        (pattern_typed implicit
          (pattern_named implicit 'self'))
        (pattern_tuple
          (pattern_typed
            (pattern_named 'application')
            (type_ident
              (component id='UIApplication' bind=none)))))
      (brace_stmt))
    (func_decl "applicationDidBecomeActive(_:)" type='<null type>'
      (body_params
        (pattern_typed implicit
          (pattern_named implicit 'self'))
        (pattern_tuple
          (pattern_typed
            (pattern_named 'application')
            (type_ident
              (component id='UIApplication' bind=none)))))
      (brace_stmt))
    (func_decl "applicationWillTerminate(_:)" type='<null type>'
      (body_params
        (pattern_typed implicit
          (pattern_named implicit 'self'))
        (pattern_tuple
          (pattern_typed
            (pattern_named 'application')
            (type_ident
              (component id='UIApplication' bind=none)))))
      (brace_stmt))))
由于不了解編譯器相關(guān)的知識,無法解析上述輸出,但是看起來很像common lisp 的“點對”數(shù)據(jù)結(jié)構(gòu)。



另外,我們會注意到另一個比較重要的命令行參數(shù):-repl,我們一起玩玩,看看這個工具能力怎么樣。

在命令行執(zhí)行如下命令:

xcrun swift -repl
可以得到一個腳本解析器的執(zhí)行環(huán)境:


我們參考“The Swift Programming Language”寫一個Hello World,看看效果:

可以使用:Ctrl + D退出解析器。

這里可以得到:

1、swift既可以被編譯執(zhí)行,也可以被解析執(zhí)行,是真正的動態(tài)語言。

2、大家可以用這個工具來學(xué)習(xí)語言特性。

 

就分析到這里,希望對大家有幫助。


原文地址http://blog.csdn.net/proteas/article/details/28439601


您還未登錄,請先登錄

熱門帖子

最新帖子

?