scheme_scheme协议 - CSDN
精华内容
参与话题
  • Scheme语言入门

    千次阅读 2019-05-17 10:42:28
    4.6.1.Scheme语言入门 最早听说 LISP,是 Stallman 的 GNU Emacs 中将 LISP 作为嵌入语言,定制和增强 Emacs。GNU Emacs 是一个文本编辑器,文本就是一种符号,而 Lisp 正好就是针对符号计算发明的,因此在GNU ...

    4.6.1. Scheme语言入门

    最早听说 LISP,是 Stallman 的 GNU Emacs 中将 LISP 作为嵌入语言,定制和增强 Emacs。GNU Emacs 是一个文本编辑器,文本就是一种符号,而 Lisp 正好就是针对符号计算发明的,因此在GNU Emacs 中使用 Lisp 是顺理成章的事情。

    Lisp 语言的历史已经很久了,几乎与 Fortran 一样长。二十世纪五十年代,计算机科学家先是发明了针对数字计算的 Fortran 语言,后来针对符号计算,由MIT 的John McCarthy于1960年开发出了Lisp(List processing)语言。该语言原来是为表处理而设计的编程语言,后来广泛用于处理人工智能问题。Lisp 程序中充满了一对对嵌套的小括号,这些嵌套的符号表达式体现着递归。递归是数学上的基本概念之一,从递归理论出发,一切可以计算的函数最终都可以划归为几种基本的递归函数的种种组合。

    1994年时众多 Lisp 版本又得到了相当的统一,统一之后的版本称为Common LISP。Common Lisp 含有非常丰富的库,仅仅语言的规范就长达千页以上,包括面向对象的 CLOS。

    Scheme 语言是 Lisp 的一个现代变种、方言,诞生于1975年,由 MIT 的 Gerald J. Sussman and Guy L. Steele Jr. 完成。Scheme语言的规范很短,总共只有50页,甚至连Common Lisp 规范的索引的长度都不到,但是却被称为是现代编程语言王国的皇后。它与以前和以后的 Lisp 实现版本都存在一些差异,但是却易学易用。

    DSSSL需要完成的工作是解析文档,它的设计就采用了Scheme语言。本书时介绍DocBook的专著,因此并不打算写一个Scheme大全,只是想通过蜻蜓点水的介绍使读者认识Scheme,能够达到看懂和简单的修改DSSSL。

    4.6.1.1. Scheme特点

    Scheme语言具有它独特的魅力,看看Scheme的语法特点:

    • 括号嵌套

      Lisp 程序中充满了一对对嵌套的小括号,这些嵌套的符号体现了最基本的数学思想——递归。

    • 语法简洁

      Scheme语言的规范很短,总共只有50页。

    • 函数编程语言

      一个函数(Function)是这个编程语言中所谓的第一等的公民。也就是说函式可以像一个 int 或者 float 一样被很方便的传递来传递去。这也就是所谓"Functional 编程语言"中,Functional 一词的由来。

    • 自动内存管理

      自动内存管理可不是JAVA的专利呦。

    • 可移植性好

      Scheme开发的程序有很好的可移植性,这是由于Scheme是一种解释语言,在不同的平台都可以有相应的解释器。

    • 适合于作为脚本语言和嵌入语言

      语法简洁,这使得Scheme的实现可以非常的经济,一个Scheme解释器可以非常的小巧。Scheme可以作为脚本语言而内嵌于一些工具之中,如:GNU Emacs。

    其他特点还有,关键字对大小写不敏感。

    4.6.1.2. 数据结构

    • 数字

      下面都是合法的数字表示方法:47,1/3,2.3,4.3e14,1+3i。

    • 字符

      字符前面需要用#\做前缀。如下面都是合法字符:

      #\a #\A #\b #\B #\space #\newline

    • 字符串

      由双引号括起来的字符组成字符串。如:"A little string"

    • 布尔值

      布尔值True和False分别用 #t 和 #f 表示。

    • 列表

      用圆括号括起来的,可以包含任何数据类型的称为列表。如: (a little (list of) (lists))

    • 数组(vector)

      用#为前缀,如: #(1 2 "string" #\x 5)

    • 函数(或称为过程)

      把函数作为一种数据类型,是Scheme语言的特色。

    • 符号

      符号除了不能够以数字开头的任何字符可组成符号。如:Symbols: this-is-a-symbol foo a32 c$23*4&7+3-is-a-symbol-too!

    4.6.1.3. 表达式和函数

    4.6.1.3.1. 注释

    分号开始一段注释。如:

    (+ 3 1) ;return 4
    

    4.6.1.3.2. 常量表达式

    1. 常量表达式

      常量表达式返回本身的值。如:

      3.14	; 返回 3.14
      #t	; 返回布尔值 #t
      #\c	; 返回字符 #\c
      "Hi!"	; 返回字符串 "Hi!"
      
    2. 引用(Quotation)

      语法:(quote obj) 或者简写为 'obj

      (+ 2 3)  	; 返回 5
      '(+ 2 3) 	; 返回列表 (+ 2 3)
      (quote (+ 2 3)) ; 返回列表 (+ 2 3)
      

    4.6.1.3.3. 表达式记法

    Scheme的表达式的写法有些特别,表达式用括号括起来。括号里面的第一个出线的是函数名或者操作符,其它是参数。Scheme的这种表达式写法可以叫做前置式。下面是一些Scheme的表达式的例子以及其对应的C语言的写法。

      Scheme                               C
    ------------------------------------------------------------------
    (+ 2 3 4)                       (2 + 3 + 4) 
    (< low x high)                  ((low < x) && (x < high)) 
    (+ (* 2 3)                      (* 4 5)) ((2 * 3) + (4 * 5)) 
    (f x y)                         f(x, y) 
    (define (sq x) (* x x))         int sq(int x) { return (x * x) } 
    
    

    4.6.1.3.4. 赋值和函数定义

    1. let 表达式和赋值

      语法:(let ((var val) ...) exp1 exp2 ...)

      说明:let 表达式的赋值只在表达式内部有效。

      示例:

      (let ((x 2) (y 3)) (+ x y))
      

      ; 先赋值: x=2, y=3,再计算x+y的值,结果为5。注意 (x 2) 和 (y 3) 外还有一层括号。

      更多的示例:

      (let ((f +))
        (f 2 3))  ; return 5 
      
      (let ((f +) (x 2))
        (f x 3))  ; return 5 
      
      (let ((f +) (x 2) (y 3))
        (f x y))  ; return 5 
      
    2. 用define 和 set! 赋值

      语法:(define var exp) , (set! var exp)

      说明:define和 set! 表达式的赋值在全局有效。define 和 set! 的区别是define既能赋值又能定义变量,而set!只能对已经定义的变量赋值。

      示例:

      (define a 1)	 
      a				; return 1
      (set! a 2)
      a				; return 2
      (let ((a 3)) a) 		; return 3
      a				; return 2
      (let ((a 3)) (set! a 4) a)	; return 4
      a				; return 2
      (let ((a 3)) (define a 5) a)	; return 5
      a				; return 2
      (set! b 1)			; 错误,b尚未定义
      
      

       

    3. lambda 表达式和函数定义

      语法:(lambda (var ...) exp1 exp2 ...)

      说明:lambda 表达式用于定义函数。var ... 是参数,exp1 exp2 ...是函数的执行 部分。通常需要结合局部定义 let 或者全局定义表达式 define,再进行函数调用。

      示例:

      ((lambda (x) (+ x x)) (* 3 4))  ; return 24
      

      说明:先用lambda定义了函数,参数是x,函数返回x+x。同时该语句也完成了函数调用,实参是 12 (等于3*4),因此返回值是 24 (等于12+12)。

    4. 在let表达式中定义函数。

      Scheme语言中,函数作为一种数据类型,通过赋值语句,将lambda表达式赋值给相应的函数。

      示例:

      (let ((double (lambda (x) (+ x x))))
        (list (double (* 3 4))
              (double (/ 99 11))
              (double (- 2 7))))     ; return (24 18 -10) 
      

      说明:let表达式将lambda定义的函数赋值给double,参数是x,返回 x+x。接下来分别三次调用 double 函数,并将结果以列表形式返回。list 表达式负责生成列表。

    5. 用define全局定义表达式来定义函数。

      用 let 定义的函数只能在 let 表达式中有效,如果想定义在整个程序中有效的函数定义,需要用到全局定义表达式——define。

      示例:

      (define double (lambda (x) (+ x x)))
      (double 12)            ; return 24
      (double (* 3 4))       ; return 24
      

      说明:define表达式定义了全局有效的函数 double。两次调用double的返回值都是 24。

    6. 定义函数的简写

      用 define 定义的函数的语法可以简化,即将 lambda 去掉。即将语法

      (define var0
        (lambda (var1 ... varn)
          e1 e2 ...)) 
      

      简写为:

      (define (var0 var1 ... varn)
        e1 e2 ...) 
      

      示例:

      (define (double x) (+ x x))
      (double 12)            ; return 24
      (double (* 3 4))       ; return 24
      

      说明:本例是前一个例子的简化版本。更简介,明了。

    4.6.1.3.5. 顺序计算表达式

    语法:(begin exp1 exp2 ...)

    说明:顺序执行表达式 exp1, exp2, ...,返回最后一个表达式的结果

    示例:

    (define x 3)
    (begin
      (set! x (+ x 1))
      (+ x x))             ; 返回结果 8
    

    说明:begin 表达式,依次先用set!表达式为x赋值为4,在运算x+x,返回结果8。

    4.6.1.3.6. 条件表达式

    1. 关系运算符

      (< -1 0)  		#t
      (> -1 0)  		#f 
      (eqv? 'a 'a) 		#t
      
      
    2. 逻辑运算

      (not #t)  		#f
      (not #f) 		#t 
      
      (not 1)  		#f
      (not '(a b c))  	#f 
      
      
      (or)  			#f
      (or #f)  		#f
      (or #f #t)  		#t
      (or #f 'a #f)  		a 
      
      (and)  			#t
      (and #f)  		#f
      (and #f #t)  		#f
      (and #f 'a #f)  	#f
      (and 'a #t 'b)		'b
      
    3. if 表达式

      语法:(if test consequent alternative)

      说明:如果test表达式为真,返回 consequent,否则返回 alternative。

      示例:

      (define (abs n)
          (if (< n 0)
              (- 0 n)
              n)) 
      
      

      说明:函数abs功能为取绝对值。

    4. cond 表达式

      语法:(cond (test exp) ... (else exp))

      说明:多路分支判断表达式,类似于C语言的 "if ... else if ... else"。

      示例:

      (define abs
        (lambda (n)
          (cond
            ((= n 0) 0)
            ((< n 0) (- 0 n))
            (else n)))) 
      
      

      说明:用cond表达式重新实现取绝对值函数 abs。

    5. case 表达式

      语法:(case exp0 clause1 clause2 ... )

      clause 的语法结构为:((key1 ...) exp1 ...) 最后一个表达式的结构可以为:(else exp1 exp2 ...)

      说明:类似于C语言的 "switch ... case..." 语句。

      示例:

      (let ((x 4) (y 5))
        (case (+ x y)
          ((1 3 5 7 9) 'odd)
          ((0 2 4 6 8) 'even)
          (else 'out-of-range)))
      ; 返回 odd
      

      说明:case 表达式先计算 x+y 的值为9,接下来在key中进行匹配,并返回对应的表达式的值 'odd。

    4.6.1.3.7. 循环

    1. do 表达式

      语法:(do ((var1 val1 update1) ...) (test res ...) exp ...)

      说明:类似于C语言的for循环。先将val1赋值给var1,...,之后循环开始,在每次循环的开始,先执行表达式 test,如果返回布尔值真,则循环终止,并返回结果 res,如果表达式 test返回布尔值#f,则运行表达式 exp...,之后依次用 update1 ... 的值来为变量 var1 ... 重新赋值。

      示例1:计算阶乘 n! = n*(n-1)!

      (define factorial
        (lambda (n)
          (do ((i n (- i 1)) (a 1 (* a i)))
              ((zero? i) a)))) 
      
      (factorial 10)  ; 返回 3628800 
      

      说明:其对应的C语言实现如下

      long factorial(int n)
      {
      	int  i=n;
      	long a=1;
      	
      	for (i=n;; i--)
      	{
      		if (i == 0)
      			return a;
      		a *= i;
      	}
      }
      

      示例2:计算fibonacci数列:f(n+1)=f(n)+f(n-1) , n>0, f(1)=1, f(0)=0

      (define fibonacci
        (lambda (n)
          (if (= n 0)
              0
              (do ((i n (- i 1)) (a1 1 (+ a1 a2)) (a2 0 a1))
                  ((= i 1) a1))))) 
      
      (fibonacci 6)  ; 返回 8
      

      说明:其对应的C语言实现如下

      long fibonacci(int n)
      {
      	long f=1;
      	
      	int i = n;
      	int a1= 1;
      	int a2= 0;
      	
      	if (n == 0)
      		return 0;
      	while(1)
      	{
      		if (i == 1)
      			return a1;
      		i--;
      		a1=a1+a2;
      		a2=a1;
      	}
      }
      
    2. map 表达式

      语法:(map procedure list1 list2 ...)

      说明:列表 list1 list2 ... 必须具有同样的长度;过程 procedure 接受的参数个数同列表的个数,各个列表中对应的变量分别作为过程 procedure 的参数被执行, 将每次的运算结果以列表形式返回。

      (map abs '(1 -2 3 -4 5 -6)) 	; 返回 (1 2 3 4 5 6),abs接受一个参数
      
      (map (lambda (x y) (* x y))
           '(1 2 3 4)
           '(8 7 6 5))		返回(8 14 18 20) ,lambda (x y) 接收两个参数
      
    3. for-each 表达式

      语法:(for-each procedure list1 list2 ...)

      说明:同 map表达式, 但是不返回结果列表。

     

     

    原文1:http://www.worldhello.net/doc/docbook_howto/ar01s04s06.html

    原文2:https://my.oschina.net/zhoukuo/blog/349453

    展开全文
  • scheme语言中文教程

    2018-01-25 13:00:20
    该中文教程详细介绍了scheme语言的语法,规则,是初学者的入门好教材
  • Scheme协议详细介绍

    千次阅读 2018-08-03 14:23:16
    1.URL Scheme使用场景介绍 2.URL Scheme基础介绍 2.1 什么是URL Scheme? 2.2 URL Scheme协议格式解释 2.3 Scheme链接格式样式 3.URL Scheme如何使用 3.1 设置Scheme 3.2 获取Scheme跳转的参数,并添加跳转...

    目录介绍

    • 1.URL Scheme使用场景介绍
    • 2.URL Scheme基础介绍
      • 2.1 什么是URL Scheme?
      • 2.2 URL Scheme协议格式解释
      • 2.3 Scheme链接格式样式
    • 3.URL Scheme如何使用
      • 3.1 设置Scheme
      • 3.2 获取Scheme跳转的参数,并添加跳转方式
      • 3.3 调用方式
      • 3.4 如何判断一个Scheme是否有效
      • 3.5 Scheme在短信息中注意要点

    好消息

    • 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计47篇[近20万字],转载请注明出处,谢谢!
    • 链接地址:https://github.com/yangchong211/YCBlogs
    • 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!

    关于Scheme应用案例

    关于链接

    1.URL Scheme使用场景介绍

    • URL Scheme使用场景,目前1,2,5使用场景很广,有没有一种熟悉的感觉?
      • 1.通过小程序,利用Scheme协议打开原生app
      • 2.H5页面点击锚点,根据锚点具体跳转路径APP端跳转具体的页面
      • 3.APP端收到服务器端下发的PUSH通知栏消息,根据消息的点击跳转路径跳转相关页面
      • 4.APP根据URL跳转到另外一个APP指定页面
      • 5.通过短信息中的url打开原生app

    2.URL Scheme基础介绍

    2.1 什么是URL Scheme?

    • android中的scheme是一种页面内跳转协议,是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面

    2.2 URL Scheme协议格式

    String urlStr="http://www.ycbjie.cn:80/yc?id=hello&name=cg";
    //url =            protocol + authority(host + port) + path + query
    //协议protocol=    http
    //域名authority=   www.ycbjie.cn:80
    //页面path=          /yc
    //参数query=       id=hello&name=cg
    //authority =      host + port
    //主机host=        www.ycbjie.cn
    //端口port=        80
    

    2.3 Scheme链接格式样式

    • 样式:[scheme]?/[host]/[path]?[query]

    3.URL Scheme如何使用

    3.1 设置Scheme

    • 在AndroidManifest.xml中对标签增加设置Scheme
    <activity
        android:name=".ui.main.ui.activity.SchemeFirstActivity"
        android:screenOrientation="portrait">
        <!--Android 接收外部跳转过滤器-->
        <!--要想在别的App上能成功调起App,必须添加intent过滤器-->
        <intent-filter>
            <!-- 协议部分配置 ,注意需要跟web配置相同-->
            <!--协议部分,随便设置 yc://ycbjie:8888/from?type=yangchong  -->
            <data android:scheme="yc"
                android:host="ycbjie"
                android:path="/from"
                android:port="8888"/>
    
    
            <!--下面这几行也必须得设置-->
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <action android:name="android.intent.action.VIEW" />
        </intent-filter>
    </activity>
    

    3.2 获取Scheme跳转的参数,并添加跳转方式

    public class SchemeFirstActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Uri uri = getIntent().getData();
            if (uri != null) {
                //获取指定参数值
                String type = uri.getQueryParameter("type");
                Log.e( "UrlUtils","main: " + type);
    
                if(type.equals("yangchong")){
                    ActivityUtils.startActivity(GuideActivity.class);
                }else if(type.equals("main")){
                    ActivityUtils.startActivity(MainActivity.class);
                }
            }
            finish();
        }
    }
    

    3.3 调用方式

    • 3.3.1 原生调用
    Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("yc://ycbjie:8888/from?type=yangchong"));
    startActivity(intent);
    
    • 3.3.2 网页调用
    <a href="yc://ycbjie:8888/from?type=yangchong">打开叮咚app</a>
    
    • 3.3.3 短信息中调用

    3.4 如何判断一个Scheme是否有效

    PackageManager packageManager = getPackageManager();
    Intent intent = new Intent(Intent.ACTION_VIEW,
            Uri.parse("yc://ycbjie:8888/from?type=yangchong"));
    List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
    boolean isValid = !activities.isEmpty();
    if (isValid) {
        startActivity(intent);
    }
    

    3.5 Scheme在短信息中注意要点

    • 设置android:scheme="http"或者android:scheme="https"后,点击短信息或者h5页面,发现没有跳到指定的页面,反而打开的是网页链接。

    关于我的博客

    展开全文
  • Scheme定义 Scheme 编程语言是一种Lisp方言,诞生于1975年,由 MIT 的 Gerald J. Sussman 和 Guy L. Steele Jr. 完成。它是现代两大Lisp方言之一;另一个方言是Common Lisp。 Scheme遵循极简主义哲学,以一个小型...

    Scheme定义

    Scheme 编程语言是一种Lisp方言,诞生于1975年,由 MIT 的 Gerald J. Sussman 和 Guy L. Steele Jr. 完成。它是现代两大Lisp方言之一;另一个方言是Common Lisp

    Scheme遵循极简主义哲学,以一个小型语言核心作为标准,加上各种强力语言工具(语法糖)来扩展语言本身。

    MIT曾用Scheme作为计算机系入门课程的编程语言。计算机程序语言界著名的魔法书《计算机程序的构造和解释》(又称SICP)正是利用Scheme来解释程序设计。

    历史悠久的Scheme依然活跃,拥有针对各种计算机平台和环境的实现,例如RacketGuile、MIT Scheme、Chez Scheme等。Guile是GNU工具体系里最重要的部件之一,被许多自由软件和开源软件作为内置脚本语言使用。

    历史与特点:

    Lisp 语言历史悠久,在计算机程序语言里,年龄仅次于Fortran。二十世纪五十年代,计算机科学家先是发明了针对数字计算的 Fortran 语言,后来针对符号计算,由MIT 的John McCarthy于1960年开发出了Lisp (list processing)语言。该语言起初为表处理而设计,后来广泛用于人工智能。Lisp 程序中充满了一对对嵌套的小括号,这些嵌套的符号表达式体现了递归。1994年时众多Lisp版本得到了相当的统一,统一之后的版本称为Common LISPCommon Lisp带有庞大的函数库,语言的规范长达千页以上,包括面向对象的 CLOS。

    Scheme语言的规范很短,总共只有50页,甚至连Common Lisp 规范的索引的长度都不到,但是却被称为是现代编程语言王国的皇后。它与以前和以后的 Lisp 实现版本都存在一些差异。现特征如下:

    (1)括号嵌套:Lisp 程序中充满了一对对嵌套的小括号,这些嵌套的符号体现了最基本的数学思想——递归

    (2)语法简洁:Scheme语言的规范很短,总共只有50页。

    (3)函数编程语言

    一个函数(Function)是这个编程语言中所谓的第一等的公民。也就是说函式可以像一个 int 或者 float 一样被很方便的传递来传递去。这也就是所谓“Functional编程语言”中,Functional 一词的由来。

    (4)自动内存管理

    (5)支持尾递归:提高了递归效率

    (6)continuation

    (7)可移植性好

    Scheme开发的程序有很好的可移植性,这是由于Scheme在不同的计算机平台有相应的解释器和编译器。

    (8)脚本语言

    由于scheme语法简洁,一个Scheme解释器可以非常的小巧。Scheme可以作为脚本语言而内嵌于一些工具之中。

    (9)数据结构

    I.数字

    下面都是合法的数字表示方法:47,1/3,2.3,4.3e14,1+3i。

    II.字符

    字符前面需要用#\做前缀。如下面都是合法字符:#\a #\A #\b #\B #\space #\newline

    III.字符串:由双引号括起来的字符组成字符串。如:"A little string"

    IV布尔值:布尔值True和False分别用 #t 和 #f 表示。

    V.列表:用圆括号括起来的,可以包含任何数据类型的称为列表。如:(a little (list of) (lists))

    VI.数组(vector):用#为前缀,如:#(1 2 "string" #\x 5)

    VII.函数(或称为过程):把函数作为一种数据类型,是包括Scheme语言在内的Lisp的特色。

    VIII.符号

    符号除了不能够以数字开头的任何字符可组成符号。如:Symbols: this-is-a-symbol foo a32 c$23*4&7+3-is-a-symbol-too!

    IX.注释 分号开始一行注释。 如:(+ 3 1) ;return 4

    Scheme应用实例

    今天小编给大家讲解的这个例子是关于shareinstall的。我们知道,Shareinstall其实是一个APP的推广辅助工具,它主要的作用就是进行渠道统计。另外,它还提供了免填二维码、一键跳转、自动渠道打包、自动建立社区关系等功能。而scheme语言主要应用在一键跳转功能上。

    以IOS SDK为例,ShareInstall通过标准的scheme、universal link等技术,在app安装的情况下,从各种浏览器(微信、QQ、新浪微博、钉钉等主流社交软件的内置浏览器)唤醒 app 并传递自定义参数,避免重复安装。

    我们可以从universal link配置作为载体,去观察scheme的活跃性。如下:

    Universal link是iOS9的一个新特性,通过Universal link,App可以通过各种浏览器跳转到App(例如微信内可不通过safari,一键跳转到App),真正实现一键跳转到相应界面。 备注:iOS9以上推荐使用Universal link。

    (1)配置developer.apple.com的相关信息 

    到苹果开发者中心,为当前的App ID开启Associated Domains服务: 

    (2)配置Xcode

    在Xcode中配置ShareInstall为当前应用生成的关联域名:Associated Domains 开关打开,添加 Domains:applinks:f6bkarebhf22eb.shareinstall.com

     在AppDelegate中的continueUserActivity方法中调用,用来处理Universal link。

    //Universal Links 通用链接
    - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
    {
        //判断是否通过ShareInstall Universal Links 唤起App
        if ([ShareInstallSDK continueUserActivity:userActivity]) {
            return YES ;
        }else{
            //其他代码
            return YES;
        }
    }
    

    (3)配置App的URL Scheme

    iOS系统中App之间是相互隔离的,通过URL Scheme, App之间可以相互调用,并且可以传递参数。 备注:iOS9以下通过Url Scheme实现拉起。

    (4) 在Xcode里选中Target—Info—URL Types, 配置shareInstall为当前应用生成的Url Scheme,如图所示:

    identifier 配置为 com.ShareInstall,URL Schemes从shareInstall获取(dekf0466)。 注:identifier 一定要配置为com.ShareInstall 

    (5) URL Scheme相关代码配置

    注意:当需要在shareInstall这个方法中处理第三方回调的时候(比如支付宝、微信回调等),请注意区分。

    //iOS9以下 URI Scheme
    -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
    
        //判断是否通过ShareInstall URL Scheme 唤起App
        if ([ShareInstallSDK handLinkURL:url]) {
             return YES;
        }else{
            //其他代码
            return YES;
        }
    
        return YES;
    }
    
    //iOS9以上 URL Scheme
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(nonnull NSDictionary *)options
    {
        //判断是否通过ShareInstall URL Scheme 唤起App
        if ([ShareInstallSDK handLinkURL:url]) {
    
            return YES;
        }else{
            //其他代码
            return YES;
        }
    
        return YES;
    }

    (6)获取唤醒参数,直达具体页

    通过在url中附带具体的参数,唤醒app并跳转到具体页。

    - (void)getWakeUpParamsFromSmartInstall: (id) params withError: (NSError *) error{
    NSLog(@"唤醒参数params=%@",params);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"URL shceme 进来的" message:[self DataTOjsonString:params] delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
    //弹出提示框(便于调试,调试完成后删除此代码)
    [alert show];
    }

    (7) 其他代码配置

    如果做测试,获取参数,则必须在Appdelegate.h加上如下测试代码。

    #pragma mark 将oc数据类型转成NSString
    -(NSString *)DataTOjsonString:(id)object
    {
        if (!object) {
            return null;
        }
    
        NSString *jsonString = null;
        NSError *error;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object
                                                           options:NSJSONWritingPrettyPrinted
                                                             error:&error];
        if (! jsonData) {
            NSLog(@"Got an error: %@", error);
        } else {
    jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        }
        return jsonString;
    }

    一键跳转的优势

    通过 URL Scheme 和 Universal Links 实现了在不同浏览器中拉起APP。这样Shareinstall SDK就减少了应用的代码冗余,提供了通用的一键拉起接口,使用户有了更加舒适的体验,同时给移动开发者对自己产品的管理和推广,也提供了便利。

     

    展开全文
  • Scheme 语言概要(上)

    万次阅读 2015-08-27 18:06:45
    作为Lisp 变体,Scheme 是一门非常简洁的计算语言,使用它的编程人员可以摆脱语言本身的复杂性,把注意力集中到更重要的问题上,从而使语言真正成为解决问题的工具。本文分为上、 下两部分来介绍 scheme 语言。 ...
    

    作为Lisp 变体,Scheme 是一门非常简洁的计算语言,使用它的编程人员可以摆脱语言本身的复杂性,把注意力集中到更重要的问题上,从而使语言真正成为解决问题的工具。本文分为上、 两部分来介绍 scheme 语言。

    一.Scheme语言的特点

    Scheme语言是LISP语言的一个方言(或说成变种),它诞生于1975年的MIT,对于这个有近三十年历史的编程语言来说,它并没有象C++,java,C#那样受到商业领域的青睐,在国内更是显为人知。但它在国外的计算机教育领域内却是有着广泛应用的,有很多人学的第一门计算机语言就是Scheme语言。

    它是一个小巧而又强大的语言,作为一个多用途的编程语言,它可以作为脚本语言使用,也可以作为应用软件的扩展语言来使用,它具有元语言特性,还有很多独到的特色,以致于它被称为编程语言中的"皇后"。

    下面是洪峰对Scheme语言的编程特色的归纳:

    • 词法定界(Lexical Scoping)
    • 动态类型(Dynamic Typing)
    • 良好的可扩展性
    • 尾递归(Tail Recursive)
    • 函数可以作为值返回
    • 支持一流的计算连续
    • 传值调用(passing-by-value)
    • 算术运算相对独立

    本文的目的是让有编程基础(那怕是一点点)的朋友能尽快的掌握Scheme语言的语法规则,如果您在读完本文后,发现自己已经会用Scheme语言了,那么我的目的就达到了。


    二.Scheme语言的标准与实现

    R5RS (Revised(5) Report on the Algorithmic Language Scheme)

    Scheme语言的语法规则的第5次修正稿,1998年制定,即Scheme语言的现行标准,目前大多数Scheme语言的实现都将达到或遵循此标准,并且几乎都加入了一些属于自己的扩展特色。

    Guile (GNU's extension language)

    Guile是GNU工程的一个项目,它是GNU扩展语言库,它也是Scheme语言的一个具体实现;如果你将它作为一个库打包,可以把它链接到你的应用程序中去,使你的应用程序具有自己的脚本语言,这个脚本语言目前就是Scheme语言。

    Guile可以在LINUX和一些UNIX系统上运行,下面是简单的安装过程:

    下载guile-1.6.4版,文件名为guile-1.6.4.tar.gz,执行下面的命令:

    tar xvfz guile-1.6.4.tar.gz
    cd guile-1.6.4
    ./configure
    make
    make install

    如此,即可以执行命令guile,进入guile>提示符状态,输入调试Scheme程序代码了,本文的所有代码都是在guile下调试通过。

    其它实现

    除了Guile外,Scheme语言的实现还有很多,如:GNU/MIT-Scheme, SCI,Scheme48,DrScheme等,它们大多是开源的,可以自由下载安装使用,并且跨平台的实现也很多。你会发现既有象basic的Scheme语言解释器,也有将Scheme语言编译成C语言的编译器,也有象JAVA那样将Scheme语言代码编译成虚拟机代码的编译器。


    三.基本概念

    注释

    Scheme语言中的注释是单行注释,以分号[;]开始一直到行尾结束,其中间的内容为注释,在程序运行时不做处理,如:

    		; this is a scheme comment line.

    标准的Scheme语言定义中没有多行注释,不过在它的实现中几乎都有。在Guile中就有多行注释,以符号组合"#!"开始,以相反的另一符号组合"!#"结束,其中内容为注释,如:

    #!
    there are scheme comment area.
    you can write mulity lines here . 
    !#

    注意的是,符号组合"#!"和"!#"一定分做两行来写。

    Scheme用做脚本语言

    Scheme语言可以象sh,perl,python等语言那样作为一种脚本语言来使用,用它来编写可执行脚本,在Linux中如果通过Guile用Scheme语言写可执行脚本,它的第一行和第二行一般是类似下面的内容:

    #! /usr/local/bin/guile -s
    !#

    这样的话代码在运行时会自动调用Guile来解释执行,标准的文件尾缀是".scm"。

    块(form)

    块(form)是Scheme语言中的最小程序单元,一个Scheme语言程序是由一个或多个form构成。没有特殊说明的情况下 form 都由小括号括起来,形如:

    (define x 123)
    (+ 1 2)
    (* 4 5 6)
    (display "hello world")

    一个 form 也可以是一个表达式,一个变量定义,也可以是一个过程。

    form嵌套

    Scheme语言中允许form的嵌套,这使它可以轻松的实现复杂的表达式,同时也是一种非常有自己特色的表达式。 下图示意了嵌套的稍复杂一点的表达式的运算过程:

    变量定义

    可以用define来定义一个变量,形式如下:
    (define 变量名 值)

    如: (define x 123) ,定义一个变量x,其值为123。

    更改变量的值

    可以用set!来改变变量的值,格式如下:
    (set! 变量名 值)

    如: (set! x "hello") ,将变量x的值改为"hello" 。

    Scheme语言是一种高级语言,和很多高级语言(如python,perl)一样,它的变量类型不是固定的,可以随时改变。


    四.数据类型

    1. 简单数据类型

    逻辑型(boolean)

    最基本的数据类型,也是很多计算机语言中都支持的最简单的数据类型,只能取两个值:#t,相当于其它计算机语言中的 TRUE;#f,相当于其它计算机语言中的 FALSE。

    Scheme语言中的boolean类型只有一种操作:not。其意为取相反的值,即:

    		(not #f) => #t
    		(not #t) => #f

    not的引用,与逻辑非运算操作类似

    guile> (not 1)
    #f
    guile> (not (list 1 2 3))
    #f
    guile> (not 'a)
    #f

    从上面的操作中可以看出来,只要not后面的参数不是逻辑型,其返回值均为#f。

    数字型(number)

    它又分为四种子类型:整型(integer),有理数型(rational),实型(real),复数型(complex);它们又被统一称为数字类型(number)。

    如:复数型(complex) 可以定义为 (define c 3+2i)
    实数型(real)可以定义为 (define f 22/7)
    有理数型(rational)可以定义为 (define p 3.1415)
    整数型(integer) 可以定义为 (define i 123)

    Scheme语言中,数字类型的数据还可以按照进制分类,即二进制,八进制,十进制和十六进制,在外观形式上它们分别以符号组合 #b、 #o、 #d、 #x 来作为表示数字进制类型的前缀,其中表示十进制的#d可以省略不写,如:二进制的 #b1010 ,八进制的 #o567,十进制的123或 #d123,十六进制的 #x1afc 。

    Scheme语言的这种严格按照数学定理来为数字类型进行分类的方法可以看出Scheme语言里面渗透着很深的数学思想,Scheme语言是由数学家们创造出来的,在这方面表现得也比较鲜明。

    字符型(char)

    Scheme语言中的字符型数据均以符号组合 "#\" 开始,表示单个字符,可以是字母、数字或"[ ! $ % & * + - . / : %lt; = > ? @ ^ _ ~ ]"等等其它字符,如:
    #\A 表示大写字母A,#\0表示字符0,
    其中特殊字符有:#\space 表示空格符和 #\newline 表示换行符。

    符号型(symbol)

    符号类型是Scheme语言中有多种用途的符号名称,它可以是单词,用括号括起来的多个单词,也可以是无意义的字母组合或符号组合,它在某种意义上可以理解为C中的枚举类型。看下面的操作:

    guile> (define a (quote xyz))  ;  定义变量a为符号类型,值为xyz
    guile> a
    xyz
    guile> (define xyz 'a)  ; 定义变量xyz为符号类型,值为a
    guile> xyz
    a

    此处也说明单引号' 与quote是等价的,并且更简单一些。符号类型与字符串不同的是符号类型不能象字符串那样可以取得长度或改变其中某一成员字符的值,但二者之间可以互相转换。

    2. 复合数据类型

    可以说复合数据类型是由基本的简单数据类型通过某种方式加以组合形成的数据类型,特点是可以容纳多种或多个单一的简单数据类型的数据,多数是基于某一种数学模型创建的。

    字符串(string) 由多个字符组成的数据类型,可以直接写成由双引号括起的内容,如:"hello" 。下面是Guile中的字符串定义和相关操作:

    guile> (define name "tomson")
    guile> name
    "tomson"
    guile> (string-length name)  ; 取字符串的长度
    6
    guile> (string-set! name 0 #\g)  ; 更改字符串首字母(第0个字符)为小写字母g (#\g)
    guile> name
    "gomson"
    guile> (string-ref name 3)  ; 取得字符串左侧第3个字符(从0开始)
    #\s

    字符串还可以用下面的形式定义:

    guile> (define other (string #\h #\e #\l #\l #\o ))
    guile> other
    "hello"

    字符串中出现引号时用反斜线加引号代替,如:"abc\"def" 。

    点对(pair)

    我把它译成"点对",它是一种非常有趣的类型,也是一些其它类型的基础类型,它是由一个点和被它分隔开的两个所值组成的。形如: (1 . 2) 或 (a . b) ,注意的是点的两边有空格。

    这是最简单的复合数据类型,同是它也是其它复合数据类型的基础类型,如列表类型(list)就是由它来实现的。

    按照Scheme语言说明中的惯例,以下我们用符号组合 "=>" 来表示表达式的值。

    它用cons来定义,如: (cons 8 9) =>(8 . 9)

    其中在点前面的值被称为 car ,在点后面的值被称为 cdr ,car和cdr同时又成为取pair的这两个值的过程,如:

    (define p (cons 4 5))	=> (4 . 5)
    (car p)			=> 4
    (cdr p)			=> 5

    还可以用set-car! 和 set-cdr! 来分别设定这两个值:

    (set-car! p "hello")
    (set-cdr! p "good")

    如此,以前定义的 p 又变成了 ("hello" . "good") 这个样子了。

    列表(list)

    列表是由多个相同或不同的数据连续组成的数据类型,它是编程中最常用的复合数据类型之一,很多过程操作都与它相关。下面是在Guile中列表的定义和相关操作:

    guile> (define la (list 1 2 3 4 ))
    guile> la
    (1 2 3 4)
    guile> (length la)  ; 取得列表的长度
    4
    guile> (list-ref la 3)  ; 取得列表第3项的值(从0开始)
    4
    guile> (list-set! la 2 99)  ; 设定列表第2项的值为99
    99
    guile> la
    (1 2 99 4)
    guile> (define y (make-list 5 6))  ;创建列表
    guile> y
    (6 6 6 6 6)

    make-list用来创建列表,第一个参数是列表的长度,第二个参数是列表中添充的内容;还可以实现多重列表,即列表的元素也是列表,如:(list (list 1 2 3) (list 4 5 6))。

    列表与pair的关系

    回过头来,我们再看看下面的定义:

    guile> (define a (cons 1 (cons 2 (cons 3 '()))))
    guile> a
    (1 2 3)

    由上可见,a本来是我们上面定义的点对,最后形成的却是列表。事实上列表是在点对的基础上形成的一种特殊格式。

    再看下面的代码:

    guile> (define ls (list 1 2 3 4))
    guile> ls
    (1 2 3 4)
    guile> (list? ls)
    #t
    guile> (pair? ls)
    #t

    由此可见,list是pair的子类型,list一定是一个pair,而pair不是list。

    guile> (car ls)
    1
    guile> (cdr ls)
    (2 3 4)

    其cdr又是一个列表,可见用于pair的操作过程大多可以用于list。

    	guile> (cadr ls)   ; 此"点对"对象的cdr的car
    2
    guile> (cddr ls)   ; 此"点对"对象的cdr的cdr
    (3 4)
    guile> (caddr ls)   ; 此"点对"对象的cdr的cdr的car
    3
    guile> (cdddr ls)   ; 此"点对"对象的cdr的cdr的cdr
    (4)

    上在的操作中用到的cadr,cdddr等过程是专门对PAIR型数据再复合形成的数据操作的过程,最多可以支持在中间加四位a或d,如cdddr,caaddr等。

    下图表示了由pairs定义形成的列表:

    这个列表可以由pair定义为如下形式:

    (define x (cons 'a (cons 'b (cons 'c (cons 'd '())))))

    而列表的实际内容则为:(a b c d)

    由pair类型还可以看出它可以轻松的表示树型结构,尤其是标准的二叉树。

    向量(vector)

    可以说是一个非常好用的类型 ,是一种元素按整数来索引的对象,异源的数据结构,在占用空间上比同样元素的列表要少,在外观上:

    列表示为: (1 2 3 4)
    VECTOR表示为: #(1 2 3 4)
    可以正常定义:(define v (vector 3 4 5))
    也可以直接定义:(define v #(3 4 5))

    vector是一种比较常用的复合类型,它的元素索引从0开始,至第 n-1 结束,这一点有点类似C语言中的数组。

    关于向量表(vector)的常用操作过程:

    guile> (define v (vector 1 2 3 4 5))
    guile> v
    #(1 2 3 4 5)
    guile> (vector-ref v 0)	; 求第n个变量的值
    1
    guile> (vector-length v)  ; 求vector的长度
    5
    guile> (vector-set! v 2 "abc")  ; 设定vector第n个元素的值
    guile> v
    #(1 2 "abc" 4 5)
    guile> (define x (make-vector 5 6))  ; 创建向量表
    guile> x
    #(6 6 6 6 6)

    make-vector用来创建一个向量表,第一个参数是数量,后一个参数是添充的值,这和列表中的make-list非常相似。

    我们可以看出,在Scheme语言中,每种数据类型都有一些基本的和它相关的操作过程,如字符串,列表等相关的操作,这些操作过程都很有规律,过程名的单词之间都用-号隔开,很容易理解。对于学过C++的朋友来说,更类似于某个对象的方法,只不过表现的形式不同了。

    3. 类型的判断、比较、运算、转换与方法

    类型判断

    Scheme语言中所有判断都是用类型名加问号再加相应的常量或变量构成,形如:

    (类型? 变量)

    Scheme语言在类型定义中有比较严格的界定,如在C语言等一些语言中数字0来代替逻辑类型数据False,在Scheme语言中是不允许的。

    以下为常见的类型判断和附加说明:

    逻辑型:

    (boolean? #t) => #t
    (boolean? #f) => #t	因为#t和#f都是boolean类型,所以其值为#t
    (boolean? 2)  => #f	因为2是数字类型,所以其值为 #f

    字符型

    (char? #\space)	=> #t
    (char? #\newline)	=> #t	以上两个特殊字符:空格和换行
    (char? #\f)		=> #t	小写字母 f
    (char? #\;)		=> #t	分号 ;
    (char? #\5)		=> #t	字符 5	,以上这些都是正确的,所以返回值都是 #t
    (char? 5)		=> #f	这是数字 5 ,不是字符类型,所以返回 #f

    数字型

    (integer? 1)		=> #t
    (integer? 2345)	=> #t
    (integer? -90)		=> #t	以上三个数均为整数
    (integer? 8.9)		=> #f   8.9不整数
    (rational? 22/7)	=> #t
    (rational? 2.3)		=> #t
    (real? 1.2)		=> #t
    (real? 3.14159)	=> #t
    (real? -198.34)		=> #t	以上三个数均为实数型
    (real? 23)		=> #t   因为整型属于实型
    (number? 5)	=> #t
    (number? 2.345)	=> #t
    (number? 22/7)	=> #t

    其它型

    (null? '())		=> #t  ; null意为空类型,它表示为 '() ,即括号里什么都没有的符号
    (null? 5)		=> #f
    (define x 123)		定义变量x其值为123
    (symbol? x)		=> #f
    (symbol? 'x)		=> #t  ; 此时 'x 为符号x,并不表示变量x的值

    在Scheme语言中如此众多的类型判断功能,使得Scheme语言有着非常好的自省功能。即在判断过程的参数是否附合过程的要求。

    比较运算

    Scheme语言中可以用<,>,<=,>=,= 来判断数字类型值或表达式的关系,如判断变量x是否等于零,它的形式是这样的:(= x 0) ,如x的值为0则表达式的值为#t,否则为#f。

    还有下面的操作:

    (eqv? 34 34)   =>  #t
    (= 34 34)      =>  #t

    以上两个form功能相同,说明 eqv? 也可以用于数字的判断。

    在Scheme语言中有三种相等的定义,两个变量正好是同一个对象;两个对象具有相同的值;两个对象具有相同的结构并且结构中的内容相同。除了上面提到的符号判断过程和eqv?外,还有eq?和equal?也是判断是否相等的过程。

    eq?,eqv?,equal?

    eq?,eqv?和equal?是三个判断两个参数是否相等的过程,其中eq?和eqv?的功能基本是相同的,只在不同的Scheme语言中表现不一样。

    eq?是判断两个参数是否指向同一个对象,如果是才返回#t;equal?则是判断两个对象是否具有相同的结构并且结构中的内容是否相同,它用eq?来比较结构中成员的数量;equal?多用来判断点对,列表,向量表,字符串等复合结构数据类型。

    guile> (define v (vector 3 4 5))
    guile> (define w #(3 4 5))  ; w和v都是vector类型,具有相同的值#(3 4 5)
    guile> (eq? v w)
    #f					; 此时w和v是两个对象
    guile> (equal? v w)
    #t                  ; 符合equal?的判断要求

    以上操作说明了eq? 和equal? 的不同之处,下面的操作更是证明了这一点:

    guile> (define x (make-vector 5 6))
    guile> x
    #(6 6 6 6 6)
    guile> (eq? x x)    ; 是同一个对象,所以返回#t
    #t
    guile> (define z (make-vector 5 6))
    guile> z
    #(6 6 6 6 6)
    guile> (eq? x z)    ; 不是同一个对象
    #f
    guile> (equal? x z)  ; 结构相同,内容相同,所以返回#t
    #t

    算术运算

    Scheme语言中的运算符有:
    + , - , * , / 和 expt (指数运算)
    其中 - 和 / 还可以用于单目运算,如:

    (- 4)  => -4
    (/ 4)  => 1/4

    此外还有许多扩展的库提供了很多有用的过程,

    max 求最大 (max 8 89 90 213)  => 213
    min 求最小 (min 3 4 5 6 7)  => 3
    abs 求绝对值 (abs -7) ==> 7

    除了max,min,abs外,还有很多数学运算过程,这要根据你用的Scheme语言的运行环境有关,不过它们大多是相同的。在R5RS中规定了很多运算过程,在R5RS的参考资料中可以很容易找到。

    转换

    Scheme语言中用符号组合"->"来标明类型间的转换(很象C语言中的指针)的过程,就象用问号来标明类型判断过程一样。下面是一些常见的类型转换过程:

    guile> (number->string 123)  ; 数字转换为字符串
    "123"
    guile> (string->number "456")  ; 字符串转换为数字
    456
    guile> (char->integer #\a)   ;字符转换为整型数,小写字母a的ASCII码值为96
    97
    guile> (char->integer #\A)  ;大写字母A的值为65
    65
    guile> (integer->char 97)  ;整型数转换为字符
    #\a
    guile> (string->list "hello")   ;字符串转换为列表
    (#\h #\e #\l #\l #\o) 
    guile> (list->string (make-list 4 #\a)) ; 列表转换为字符串
    "aaaa"
    guile> (string->symbol "good")  ;字符串转换为符号类型
    good
    guile> (symbol->string 'better)  ;符号类型转换为字符串
    "better"

    五.过程定义

    过程(Procedure)

    在Scheme语言中,过程相当于C语言中的函数,不同的是Scheme语言过程是一种数据类型,这也是为什么Scheme语言将程序和数据作为同一对象处理的原因。如果我们在Guile提示符下输入加号然后回车,会出现下面的情况:

    guile> +
    #<primitive-procedure +>

    这告诉我们"+"是一个过程,而且是一个原始的过程,即Scheme语言中最基础的过程,在GUILE中内部已经实现的过程,这和类型判断一样,如boolean?等,它们都是Scheme语言中最基本的定义。注意:不同的Scheme语言实现环境,出现的提示信息可能不尽相同,但意义是一样的。

    define不仅可以定义变量,还可以定义过程,因在Scheme语言中过程(或函数)都是一种数据类型,所以都可以通过define来定义。不同的是标准的过程定义要使用lambda这一关键字来标识。

    Lambda关键字

    Scheme语言中可以用lambda来定义过程,其格式如下:
    (define 过程名 ( lambda (参数 ...) (操作过程 ...)))

    我们可以自定义一个简单的过程,如下:

    		(define add5 (lambda (x) (+ x 5)))

    此过程需要一个参数,其功能为返回此参数加5 的值,如:

    	    (add5 11) => 16

    下面是简单的求平方过程square的定义:

    	(define square (lambda (x)  (* x x)))

    与lambda相同的另一种方式

    在Scheme语言中,也可以不用lambda,而直接用define来定义过程,它的格式为:
    (define (过程名 参数) (过程内容 …))

    如下面操作:

    		(define (add6 x) (+ x 6))
    		add6
    		#<procedure: add6 (x)> 说明add6是一个过程,它有一个参数x
    		(add6 23)    => 29

    再看下面的操作:

    guile> (define fun
                    (lambda(proc x y)
                            (proc x y)))
    guile> fun
    #<procedure fun (proc x y)>
    guile> (fun * 5 6)
    30
    guile> (fun / 30 3)
    10

    更多的过程定义

    上面定义的过程fun有三个参数,其中第一个参数proc也是一个操作过程(因为在Scheme语言中过程也是一种数据,可以作为过程的参数),另外两个参数是数值,所以会出现上面的调用结果。

    guile> (define add
                    (lambda (x y)
                            (+ x y)))
    guile> add
    #<procedure add (x y)>
    guile> (fun add 100 200)
    300

    继续上面操作,我们定义一个过程add,将add作为参数传递给fun过程,得出和(fun + 100 200)相同的结果。

    guile> ((lambda (x) (+ x x)) 5)
    10

    上面的 (lambda(x) (+ x x)) 事实上是简单的过程定义,在后面直接加上操作参数5,得出结果10,这样实现了匿名过程,直接用过程定义来操作参数,得出运算结果。

    通过上面的操作,相信你已初步了解了过程的用法。 既然过程是一种数据类型,所以将过程作为过程的参数是完全可以的。以下过程为判断参数是否为过程,给出一个参数,用 procedure? 来判断参数是否为过程,采用if结构(关于if结构见下面的介绍):

    guile> (define isp
                (lambda (x)
                         (if (procedure? x) 'isaprocedure 'notaprocedure)))
    guile> isp
    #<procedure isp (x)>
    guile> (isp 0)
    notaprocedure
    guile> (isp +)
    isaprocedure

    上面的过程就体现了Scheme语言的参数自省(辨别)能力,'0'是数字型,所以返回notaprocedure;而'+'是一个最基础的操作过程,所以返回isaprocedure。

    过程的嵌套定义

    在Scheme语言中,过程定义也可以嵌套,一般情况下,过程的内部过程定义只有在过程内部才有效,相当C语言中的局部变量。

    如下面的代码的最终结果是50:

    (define fix 
    	(lambda (x y z)
    		(define add 
    			(lambda (a b) (+ a b)))
    		(- x (add y z))))
    (display (fix 100 20 30))

    此时过程add只在fix过程内部起做用,这事实上涉及了过程和变量的绑定,可以参考下面的关于过程绑定(let,let* 和letrec)的介绍。

    过程是初学者难理解的一个关键,随着过程参数的增加和功能的增强,过程的内容变得越来越复杂,小括号也会更多,如果不写出清晰的代码的话,读代码也会成为一个难题。

    熟悉了 scheme 基本概念、数据类型和过程(函数)后, 下一部分我们来学习 scheme 的结构、递归调用和其他扩展功能。

    展开全文
  • scheme 语言概述

    千次阅读 2015-10-07 02:13:27
    Scheme语言是LISP语言的一个方言(或说成变种),它诞生于1975年的MIT,对于这个有近三十年历史的编程语言来 说,它并没有象C++,java,C#那样受到商业领域的青睐,在国内更是显为人知。但它在国外的计算机教育领域内...
  • scheme简明教程

    2018-04-06 13:34:21
    这是一本在国外比较有名的Scheme编程语言的入门教材。本教材适合任何对Scheme编程语言感兴趣的人阅读,尤其是有其他编程语言(特别是动态语言)编程经验,希望快速了解Scheme的不同点并且快速上手写点东西的人。
  • 使用shceme跳转支付宝指定页面,从支付宝APK提取出来,key的数字就是scheme的said,自行替换即可,json里有部分是之前的支付宝的活动页面,跳转了会提示已暂停服务 //扫一扫 alipayqr://platformapi/startapp?saId=...
  • Scheme

    千次阅读 2016-08-25 12:50:59
    Scheme是一种函数式编程语言,是Lisp的两种主要方言之一(另一种为Common Lisp)。不同于Common Lisp,Scheme遵循极简主义哲学,以一个小型语言核心作为标准,加上各种强力语言工具(语法糖)来扩展语言本身。麻省...
  • 最美丽的编程语言Scheme——基本表达式

    万次阅读 热门讨论 2010-10-27 23:24:00
    Scheme被很多人誉为“世界上最美丽的编程语言”。偶也被他们的话所打动,于是乎开始了Scheme之旅。 目前Scheme大多用于科研,商用的比较少。但即便如此,也丝毫不会影像其“美丽”。 下面就请大家一起跟我走进...
  • Scheme 介绍

    万次阅读 2019-06-03 05:20:12
    最近一直在看 sicp 这本书,准备写点读书笔记,这篇当作是对 Scheme 语言的介绍,毕竟全书是用这门语言写的。 下面是我对书中使用的 mit-scheme 的一些理解,我没有正统学习过函数式或类 Lisp 语言,只有一些我自己...
  • scheme 学习

    千次阅读 2016-05-06 17:19:24
    Scheme共舞
  • Scheme归纳】3 比较do, let, loop

    万次阅读 2015-03-12 14:06:16
    str str)返回#t,因为str本身的地址的是一样的,但是”scheme”和”scheme”则被存储在不同的地址中,因此函数返回#f。注意,不要用eq?来比较数字,因为在R5RS和MIT-Scheme中均没有被指定返回值,建议使用eqv?或者=...
  • 自定义 URL Scheme 完全指南

    千次阅读 2014-05-22 14:41:43
    本文转自 Migrant的博客,原文:...iPhone / iOS SDK 最酷的特性之一就是应用将其自身”绑定”到一个自定义 URL scheme 上,该 scheme 用于从浏览器或其他应用中启动本应用。   注册自定义 URL Scheme 注册
  • The Wavelet Lifting Scheme

    2015-12-30 12:46:59
    The Wavelet Lifting Scheme At the beginning of my journey, I was naive. I didn't yet know that answers vanish as one continues to travel, that there is only further complexity, that there are s
  • Scheme入门教程(Yet Another Scheme Tutorial),从网页下载,转成PDF
  • lisp方言--scheme

    千次阅读 2012-06-10 19:29:39
    Scheme 维基百科,自由的百科全书 跳转到: 导航,搜索 汉漢▼ Scheme 编程范型 多范型 发行时间 1970年代 设计者 盖伊·史提尔二世 和 杰拉德·...
  • URI Scheme

    万次阅读 2012-03-03 13:53:13
    1. 什么是URI Scheme? 一般情况下,遇到这种概念不清的问题,最好的第一手资料就是wiki,实在看不懂,再看百度百科,但前者给出的资料一般都是更加准确一些。 以下为维基百科和百度百科关于这个问题的连接: URI ...
  • 小语种介绍:LISP/Scheme

    千次阅读 热门讨论 2006-06-11 14:11:00
    自从裘宗燕教授翻译了《计算机程序的构造和解释》(Structure and ...同时受到关注的,还有它所介绍的函数式编程(Functional Programming),以及其中范例所使用的Scheme语言。时光倒转到30年前,1975年,
  • Android Scheme协议与应用全解析

    千次阅读 2017-01-26 12:02:24
    URL Scheme 的作用 客户端应用可以向操作系统注册一个 URL Scheme,该 Scheme 用于从浏览器或其他应用中启动本应用。 通过指定的 URL 字段,可以让应用在被调起后直接打开某些特定页面,比如:书籍封面页,书城...
1 2 3 4 5 ... 20
收藏数 173,491
精华内容 69,396
关键字:

scheme