日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

007_表达式

發(fā)布時(shí)間:2025/5/22 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 007_表达式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一. 字符串

1. 在文本中確定字符串值的方法是看雙引號(hào), 比如: "some text", 或單引號(hào), 比如: 'some text'。這兩種形式是等同的。

2. 如果文本自身包含用于字符引用的引號(hào)("或')或反斜杠時(shí), 應(yīng)該在它們的前面再加一個(gè)反斜杠; 這就是轉(zhuǎn)義。轉(zhuǎn)義允許直接在文本中輸入任何字符, 也包括換行。

3. 下面的表格是FreeMarker支持的所有轉(zhuǎn)義字符。在字符串使用反斜杠的其他所有情況都是錯(cuò)誤的, 運(yùn)行這樣的模板都會(huì)失敗。

4. 在\x之后的Code是1-4位的16進(jìn)制碼。下面這個(gè)示例中都是在字符串中放置版權(quán)符號(hào): "\xA9 1999-2001", "\x0A9 1999-2001", "\x00A9 1999-2001"。如果緊跟16進(jìn)制碼后一位的字符也能解釋成16進(jìn)制碼時(shí), 就必須把4位補(bǔ)全, 否則FreeMarker就會(huì)誤解你的意圖。

5. 請(qǐng)注意, 字符序列${和#{有特殊的含義, 它們被用做插入表達(dá)式的數(shù)值(典型的應(yīng)用是變量的值: "Hello ${user}!")。如果想要打印${或#{, 就要使用下面所說(shuō)的原生字符串, 或者進(jìn)行轉(zhuǎn)義。就像"foo $\{bar}"中的{。

6. 原生字符串是一種特殊的字符串。在原生字符串中, 反斜杠和${沒(méi)有特殊含義, 它們被視為普通的字符。為了表明字符串是原生字符串, 在開始的引號(hào)或單引號(hào)之前放置字母r, 例如:

${r"${foo}"}

${r"C:\foo\bar"}

二. 數(shù)字

1. 輸入不帶引號(hào)的數(shù)字就可以直接指定一個(gè)數(shù)字, 必須使用點(diǎn)作為小數(shù)的分隔符。可以使用-或+來(lái)表明符號(hào)(+是多余的)。科學(xué)記數(shù)法暫不支持使用(1E3就是錯(cuò)誤的), 而且也不能在小數(shù)點(diǎn)之前不寫0(.5也是錯(cuò)誤的)。

2. 整數(shù)和非整數(shù)是不區(qū)分的; 只有單一的數(shù)字類型。

三. 布爾值

1. 直接寫true或者false就表示一個(gè)布爾值了, 不需使用引號(hào)。

四. 序列

1. 指定一個(gè)文字的序列, 使用逗號(hào)來(lái)分隔其中的每個(gè)子變量, 然后把整個(gè)列表放到方括號(hào)中。例如:

<#list ["foo", "bar", "baz"] as x>

${x}

</#list>

五. 值域

1. 值域也是序列, 但它們由指定包含的數(shù)字范圍所創(chuàng)建, 而不需指定序列中每一項(xiàng)。比如: 0..<m, 這里假定m變量的值是5, 那么這個(gè)序列就包含[0, 1, 2, 3, 4]。值域的主要作用有: 使用<#list...>來(lái)迭代一定范圍內(nèi)的數(shù)字, 序列切分和字符串切分。

2. 值域表達(dá)式的通用形式是(start和end可以是任意的結(jié)果為數(shù)字表達(dá)式):

2.1. start..end: 包含結(jié)尾的值域。比如, 1..4就是[1, 2, 3, 4]; 而4..1就是[4, 3, 2, 1]。當(dāng)心一點(diǎn), 包含結(jié)尾的值域不會(huì)是一個(gè)空序列, 至少有一個(gè)值。

2.2. start..<end或start..!end: 不包含結(jié)尾的值域。比如, 1..<4就是[1, 2, 3]; 4..<1就是[4, 3, 2]; 而1..<1表示[]。請(qǐng)注意最后一個(gè)示例, 結(jié)果可以是空序列。

2.3. start..*length: 限定長(zhǎng)度的值域。比如, 10..*4就是[10, 11, 12, 13]; 10..*-4就是[10, 9, 8, 7]; 而10..*0表示[]。當(dāng)這些值域被用來(lái)切分時(shí), 如果切分后的序列或者字符串結(jié)尾在指定值域長(zhǎng)度之前, 則切分不會(huì)有問(wèn)題。

2.4. start..: 無(wú)右邊界值域。這和限制長(zhǎng)度的值域很像, 只是長(zhǎng)度是無(wú)限的。比如, 1..就是[1, 2, 3, 4, 5, 6, ... ]直到無(wú)窮大。但是處理(比如列表顯示)這種值域時(shí)要萬(wàn)分小心, 處理所有項(xiàng)時(shí), 會(huì)花費(fèi)很長(zhǎng)時(shí)間, 直到內(nèi)存溢出應(yīng)用程序崩潰。和限定長(zhǎng)度的值域一樣, 當(dāng)它們被切分時(shí), 遇到切分后的序列或字符串結(jié)尾時(shí), 切分就結(jié)束了。

3. 無(wú)右邊界值域在FreeMarker 2.3.21版本以前只能用于切分, 若用于其它用途, 它就像空序列一樣了。要使用新的特性, 使用FreeMarker 2.3.21版本是不夠的, 程序員要設(shè)置incompatible_improvements至少到2.3.21版本。

4. .., ..<, ..!和..*是運(yùn)算符, 所以它們中間不能有空格。就像n .. <m這樣是錯(cuò)誤的, 但是n ..< m這樣就可以。

5. 無(wú)右邊界值域的定義大小是2147483647(如果incompatible_improvements低于2.3.21版本, 那么就是0), 這是由于技術(shù)上的限制(32位)。但當(dāng)列表顯示它們的時(shí)候, 實(shí)際的長(zhǎng)度是無(wú)窮大。

6. 值域并不存儲(chǔ)它們包含的數(shù)字, 那么對(duì)于0..1和0..100000000來(lái)說(shuō), 創(chuàng)建速度都是一樣的, 并且占用的內(nèi)存也是一樣的。

六. 哈希表

1. 在模板中指定一個(gè)哈希表, 就可以遍歷用逗號(hào)分隔開的"鍵/值"對(duì), 把列表放到花括號(hào)內(nèi)即可。鍵和值成對(duì)出現(xiàn)并以冒號(hào)分隔。比如: {"name": "green mouse", "price": 150}。請(qǐng)注意名和值都是表達(dá)式, 但是用來(lái)檢索的名稱就必須是字符串類型, 而值可以是任意類型。

七. 獲取字符

1. 在給定索引值時(shí)可以獲取字符串中的一個(gè)字符, 這和序列的子變量是相似的, 比如: str[0]。這個(gè)操作執(zhí)行的結(jié)果是一個(gè)長(zhǎng)度為1的字符串, FTL并沒(méi)有獨(dú)立的字符類型。和序列中的子變量一樣, 這個(gè)索引也必須是數(shù)字, 范圍是從0到字符串的長(zhǎng)度, 否則模板的執(zhí)行將會(huì)發(fā)生錯(cuò)誤并終止。

2. 由于序列的子變量語(yǔ)法和字符串的getter語(yǔ)法沖突, 那么只能在變量不是序列時(shí)使用字符的getter語(yǔ)法。因?yàn)镕TL支持多類型值, 變量既可以是序列, 同時(shí)也可以是字符串, 這種情況下使用序列方式就比較多。為了變通, 可以使用內(nèi)建函數(shù)string, 比如: user?string[0]。

八. 序列連接

1. 序列的連接可以按照字符串那樣使用 + 號(hào)來(lái)進(jìn)行, 例如:

<#list ["蘋果", "香蕉"] + ["葡萄", "梨子"] as fruit>

${fruit}

</#list>

2. 請(qǐng)注意, 不要在很多重復(fù)連接時(shí)使用序列連接操作, 比如在循環(huán)中往序列上追加項(xiàng)目。盡管序列連接的速度很快, 而且速度是和被連接序列的大小相獨(dú)立的, 但是最終的結(jié)果序列的讀取卻比原先的兩個(gè)序列慢那么一點(diǎn)。通過(guò)這種方式進(jìn)行的許多重復(fù)連接最終產(chǎn)生的序列讀取的速度會(huì)慢。

九. 序列切分

1. 使用seq[range], 這里range是一個(gè)值域, 就可以得到序列的一個(gè)切分。結(jié)果序列會(huì)包含原序列(seq)中的項(xiàng), 而且索引在值域中。例如:

<#assign seqs = ["蘋果", "香蕉", "葡萄", "梨子", "菠蘿"]>

<#list seqs[1..3] as seq1>

${seq1}

</#list>

2. 此外, 切分后序列中的項(xiàng)會(huì)和值域的順序相同。那么上面的示例中, 如果值域是3..1將會(huì)輸出: 梨子葡萄香蕉。

3. 值域中的數(shù)字必須是序列可使用的合法索引, 否則模板的處理將會(huì)終止并報(bào)錯(cuò)。

4. 限制長(zhǎng)度的值域(start..*length)和無(wú)右邊界值域(start..)適用于切分后序列的長(zhǎng)度。它們會(huì)切分可用項(xiàng)中盡可能多的部分。

十. 字符串切分

1. 可以按照切分序列的相同方式來(lái)切分字符串, 這就是使用字符來(lái)代替序列。不同的是:

1.1. 降序域不允許進(jìn)行字符串切分。

1.2. 如果變量的值既是字符串又是序列(多類型值), 那么切分將會(huì)對(duì)序列進(jìn)行, 而不是字符串。

1.3. 一個(gè)遺留的bug: 值域包含結(jié)尾時(shí), 結(jié)尾小于開始索引并且是是非負(fù)的(就像在"abc"[1..0]中), 會(huì)返回空字符串而不是錯(cuò)誤。現(xiàn)在這個(gè)bug已經(jīng)向后兼容, 但是不應(yīng)該使用它, 否在就會(huì)埋下一個(gè)錯(cuò)誤。

十一. 哈希表連接

1. 像連接字符串那樣, 也可以使用+號(hào)的方式來(lái)連接哈希表。如果兩個(gè)哈希表含有鍵相同的項(xiàng), 那么在+號(hào)右側(cè)的哈希表中的項(xiàng)優(yōu)先。

<#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>

Joe is ${ages.Joe}

Fred is ${ages.Fred}

Julia is ${ages.Julia}

2. 請(qǐng)注意, 很多項(xiàng)連接時(shí)不要使用哈希表連接, 比如: 在循環(huán)時(shí)往哈希表中添加新項(xiàng)。這和序列連接的情況是一致的。

十二. 算數(shù)運(yùn)算

1. 算數(shù)運(yùn)算包含基本的四則運(yùn)算和求模運(yùn)算, 運(yùn)算符有:

加法: +

減法: -

乘法: *

除法: /

求模(求余): %

2. 要保證兩個(gè)操作數(shù)都是結(jié)果為數(shù)字的表達(dá)式。下面的這個(gè)例子在運(yùn)行時(shí), FreeMarker就會(huì)發(fā)生錯(cuò)誤, 因?yàn)槭亲址?#34;5"而不是數(shù)字5:

${3 * "5"}

3. 但這種情況也有一個(gè)例外, 就是+號(hào), 它是用來(lái)連接字符串的。如果+號(hào)的一端是字符串, +號(hào)的另外一端是數(shù)字, 那么數(shù)字就會(huì)自動(dòng)轉(zhuǎn)換為字符串類型, 之后使用+號(hào)作為字符串連接操作符。

4. 通常來(lái)說(shuō), FreeMarker不會(huì)自動(dòng)將字符串轉(zhuǎn)換為數(shù)字, 反之會(huì)自動(dòng)進(jìn)行。

十三. 比較運(yùn)算

1. 測(cè)試兩個(gè)值相等使用==。

2. 測(cè)試兩個(gè)值不等使用!=。

3. ==或!=兩邊的表達(dá)式的結(jié)果都必須是標(biāo)量, 而且兩個(gè)標(biāo)量都必須是相同類型。

4. 對(duì)數(shù)字和日期類型的比較, 也可以使用<, <=, >=和>。

5. 使用>=和>的時(shí)候有一點(diǎn)小問(wèn)題。FreeMarker解釋>的時(shí)候可以把它當(dāng)作FTL標(biāo)簽的結(jié)束符。為了避免這種問(wèn)題, 可以使用lt代替<, lte代替<=, gt代替>還有g(shù)te代替>=。

十四. 邏輯操作

1. 常用的邏輯操作符

邏輯或: ||

邏輯與: &&

邏輯非: !

2. 邏輯操作符僅僅在布爾值之間有效, 若用在其他類型將會(huì)產(chǎn)生錯(cuò)誤導(dǎo)致模板執(zhí)行中止。

<#if hot < 28 && color == "blue">

??今天溫度小于28度, 并且天是藍(lán)色的。

</#if>

<#if !hot>

??今天不熱。

</#if>

十五. 賦值操作符

1. <#assign x += y>是<#assign x = x + y>的簡(jiǎn)寫。

2. <#assign x -= y>是<#assign x = x - y>的簡(jiǎn)寫。

3. <#assign x *= y>是<#assign x = x * y>的簡(jiǎn)寫。

4. <#assign x /= y>是<#assign x = x / y>的簡(jiǎn)寫。

5. <#assign x %= y>是<#assign x = x % y>的簡(jiǎn)寫。

6. <#assign x++>是<#assign x += 1>的簡(jiǎn)寫。只有后加加, 沒(méi)有前加加。

7. <#assign x-->是<#assign x -= 1>的簡(jiǎn)寫。只有后減減, 沒(méi)有前減減。

十六. 默認(rèn)值操作符

1. 使用形式: unsafe_expr!或default_expr或unsafe_expr!或(unsafe_expr)!default_expr或(unsafe_expr)!操作符允, 許你為可能不存在的變量指定一個(gè)默認(rèn)值。

2. 默認(rèn)值可以是任何類型的表達(dá)式, 也可以不必是字符串。 也可以這么寫:hits!0 或 colors!["red", "green", "blue"]。默認(rèn)值表達(dá)式的復(fù)雜程度沒(méi)有嚴(yán)格限制, 還可以這么來(lái)寫:?cargo.weight!(item.weight * itemCount + 10)。

3. 如果在!后面有復(fù)合表達(dá)式, 如: 1 + x, 通常使用括號(hào), 如: ${(x!1) + y}, 這樣就根據(jù)你的意圖來(lái)確定優(yōu)先級(jí)。由于FreeMarker2.3.x版本的源碼中的小失誤所以必須這么來(lái)做。!(作為默認(rèn)值操作)右側(cè)的優(yōu)先級(jí)非常低。這就意味著${x!1 + y}會(huì)被FreeMarker誤解為${x!(1 + y)}, 而真實(shí)的意義是${(x!1) + y}。這個(gè)源碼錯(cuò)誤在FreeMarker 2.4中會(huì)得到修正。在編程中注意這個(gè)錯(cuò)誤, 要么就使用FreeMarker 2.4!

4. 如果默認(rèn)值被省略了, 那么結(jié)果將會(huì)是空串, 空序列或空哈希表(這是FreeMarker允許多類型值的體現(xiàn))。請(qǐng)注意, 如果想讓默認(rèn)值為0或false, 則不能省略它。

5. 因?yàn)檎Z(yǔ)法的含糊<#assign a=x! b=y />將會(huì)解釋為<#assign a=x!(b=y) />, 那就是說(shuō)b=y將會(huì)被視為是比較運(yùn)算, 然后結(jié)果作為x的默認(rèn)值, 而不是想要的參數(shù)b。 為了避免這種情況, 如下編寫代碼即可: <#assign a=(x!) b=y />。

6. 用于非頂層變量時(shí), 默認(rèn)值操作符可以有兩種使用方式:

6.1. product.color!"red"如果是這樣的寫法, 那么在product中, 當(dāng)color不存在時(shí)(返回"red"), 將會(huì)被處理, 但是如果連product都不存在時(shí)將不會(huì)處理。也就是說(shuō)這樣寫時(shí)變量 product必須存在, 否則模板就會(huì)報(bào)錯(cuò)。

6.2. (product.color)!"red"這時(shí), 如果當(dāng)product.color不存在時(shí)也會(huì)被處理, 那就是說(shuō), 如果product不存在或者product存在而color不存在, 都能顯示默認(rèn)值"red"而不會(huì)報(bào)錯(cuò)。 本例和上例寫法的重要區(qū)別在于用括號(hào)時(shí), 就允許其中表達(dá)式的任意部分可以未定義。而沒(méi)有括號(hào)時(shí), 僅允許表達(dá)式的最后部分可以不被定義。

7. 當(dāng)然, 默認(rèn)值操作也可以作用于序列子變量${seq[0]!'-'}。如果序列索引是負(fù)數(shù)(比如: seq[-1]!'-')也會(huì)發(fā)生錯(cuò)誤, 不能使用該運(yùn)算符或者其它運(yùn)算符去壓制它。

. 不存在值檢測(cè)操作符

1. 使用形式: unsafe_expr??或(unsafe_expr)??操作符告訴我們一個(gè)值是否存在。基于這種情況, 結(jié)果是true或false。

2. 訪問(wèn)非頂層變量的使用規(guī)則和默認(rèn)值操作符也是一樣的, 也就是說(shuō), 可以寫product.color??和(product.color)??。

. 例子

1. 新建一個(gè)名為FMExpression的動(dòng)態(tài)Web項(xiàng)目, 同時(shí)添加相關(guān)jar包。

2. 新建FMFactory.java

package com.fm.util;import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import freemarker.template.Configuration; import freemarker.template.TemplateExceptionHandler;public class FMFactory {private final static FMFactory instance = new FMFactory();private FMFactory() {}public static FMFactory getInstance() {return instance;}private Map<String, Configuration> map = new ConcurrentHashMap<String, Configuration>();// 創(chuàng)建單個(gè)Configuration實(shí)例public synchronized Configuration getCfg(Object servletContext, String path) {if(null != map.get(path)) {return map.get(path);}Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);cfg.setServletContextForTemplateLoading(servletContext, path);cfg.setDefaultEncoding("utf-8");cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);map.put(path, cfg);return cfg;}}

3. 新建Expression.java

package com.fm.action;import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.sql.Date; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.fm.util.FMFactory; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException;public class Expression extends HttpServlet {private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Configuration cfg = FMFactory.getInstance().getCfg(req.getServletContext(), "/WEB-INF/templates");Map<String, Object> root = new HashMap<String, Object>();root.put("createTime", new Date(888888888));root.put("byeTime", new Date(999999999999L));// 獲取模板Template temp = cfg.getTemplate("expression.html");Writer out = new OutputStreamWriter(resp.getOutputStream());try {// 合并模板和數(shù)據(jù)模型temp.process(root, out);} catch (TemplateException e) {e.printStackTrace();}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);} }

4. 修改web.xml

5. 在/WEB-INF/templates下創(chuàng)建expression.html

<!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>表達(dá)式</title></head><body><h2>字符串</h2>轉(zhuǎn)義字符串:${"\""}${"\'"}${"\{"}${"\\"}${"\l"}${"\g"}${"\a"}${"\x00A9 1999-2001"}"foo $\{bar}"<br />原生字符串:${r"${foo}"}${r"C:\foo\bar"}<h2>值域</h2>帶邊界的值域:<#list 0..0 as vari>${vari}</#list><br />不帶邊界的值域:<#list 0..!0 as vari>${vari}</#list><br />限定長(zhǎng)度的值域:<#list 0..*10 as vari>${vari}</#list><h2>哈希表</h2><#-- assign指令定義變量 --><#assign hash = {"name": "蘋果", "price": 15} />${hash.name} ${hash.price}<h2>獲取字符</h2>${"我們都是中國(guó)人"[0]}<br />${"我們都是中國(guó)人"?string[1]}<h2>序列連接</h2><#list ["蘋果", "香蕉"] + ["葡萄", "梨子"] as fruit>${fruit}</#list><h2>序列切分</h2><#assign seqs = ["蘋果", "香蕉", "葡萄", "梨子", "菠蘿"]><#list seqs[1..3] as seq1>${seq1}</#list><br /><#list seqs[3..1] as seq2>${seq2}</#list><br /><#list seqs[1..*10] as seq3>${seq3}</#list><br /><#list seqs[1..] as seq4>${seq4}</#list><h2>字符串切分</h2><#assign str = "我愛吃蘋果、普通、梨子..." />${str[2..3]}<br />${str[2..!4]}<br />${str[2..*3]}<br />${str[2..]}<h2>哈希表連接</h2><#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>Joe is ${ages.Joe}<br />Fred is ${ages.Fred}<br />Julia is ${ages.Julia}<h2>比較運(yùn)算</h2>創(chuàng)建時(shí)間: ${createTime}<br />購(gòu)買時(shí)間: ${byeTime}<br /><#if createTime gt byeTime>創(chuàng)建時(shí)間大于購(gòu)買時(shí)間。<#else>創(chuàng)建時(shí)間小于購(gòu)買時(shí)間。</#if><h2>邏輯操作</h2><#assign hot = 25 color = "blue" /><#if hot lt 28 && color == "blue">今天溫度小于28度, 并且天是藍(lán)色的。</#if><#if !(hot gte 28)>今天不熱。</#if><h2>賦值操作符</h2><#assign x = 100 y = 10 />${x} + ${y} = ${(x + y)?c}<br />${x} - ${y} = ${(x - y)?c}<br />${x} * ${y} = ${(x * y)?c}<br />${x} / ${y} = ${(x / y)?c}<br />${x} % ${y} = ${(x % y)?c}<br />${x} += ${y} = <#assign x += y />${x}<br />${x} -= ${y} = <#assign x -= y />${x}<br />${x} *= ${y} = <#assign x *= y />${x}<br />${x} /= ${y} = <#assign x /= y />${x}<br />${x} %= ${y} = <#assign x %= y />${x}<br />${x}++ = <#assign x++ />${x}<br />${x}-- = <#assign x-- />${x}<br /><h2>默認(rèn)值操作符</h2>[${mouse!"No mouse."}]<br />[${mouse!}]<br />[${(mouse)!"No mouse."}]<br />[${(mouse)!}]<br />[${(product.color)!"red"}]<br />[<#assign a=z! x=y />${a?c}]<br />[<#assign a=(z!) b=y />${a}]<h2>不存在值檢測(cè)操作符</h2><#if price??>price found<#else>No price found</#if><br /><#assign price = "Jerry"><#if price??>price found<#else>No price found</#if><br /><#if (banana.price)??>banana.price found<#else>No banana.price found</#if><br /></body> </html>

6. 運(yùn)行項(xiàng)目

總結(jié)

以上是生活随笔為你收集整理的007_表达式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。