ypeScript 是一種由微軟開發的編程語言,它在 JavaScript 的基礎上增加了靜態類型和其他許多特性,旨在幫助開發人員更早地捕獲錯誤并使代碼更加健壯。本教程將帶你快速了解 TypeScript 的基礎內容,通過簡單易懂的實例,讓你輕松上手。
TypeScript 是 JavaScript 的超集,這意味著你可以在 TypeScript 中編寫任何 JavaScript 代碼,但它還添加了一些 JavaScript 沒有的特性,比如類型系統和現代 ECMAScript 的更多高級功能。
在我們開始之前,需要在本地安裝 TypeScript。你可以使用 npm(Node.js 包管理器)來完成這一步:
npm install -g typescript
安裝完成后,可以使用以下命令來檢查版本:
tsc --version
// hello.ts
const greeting: string = 'Hello, TypeScript!';
console.log(greeting);
tsc hello.ts
node hello.js
你會看到 Hello, TypeScript! 被打印到控制臺上。
TypeScript 提供了許多基礎類型,包括如下幾種:
let name: string = 'TypeScript';
console.log(`Hello, ${name}`);
let age: number = 25;
console.log(`Age: ${age}`);
let isLearning: boolean = true;
console.log(`Is learning TypeScript: ${isLearning}`);
接口用于定義對象的結構,是 TypeScript 中非常強大的一個特性。
interface Person {
firstName: string;
lastName: string;
age: number;
}
const student: Person = {
firstName: 'John',
lastName: 'Doe',
age: 20
};
console.log(`Student: ${student.firstName} ${student.lastName}, Age: ${student.age}`);
TypeScript 中的類幫助你更好地組織和封裝代碼結構。
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet(): string {
return `Hello, ${this.greeting}`;
}
}
let greeter = new Greeter('World');
console.log(greeter.greet());
使用 TypeScript 來定義函數時,可以清晰地指定參數和返回值的類型。
function add(x: number, y: number): number {
return x + y;
}
let result = add(5, 3);
console.log(`Sum: ${result}`);
泛型提供了一種方式,使得函數和類可以處理多種類型,同時提供強類型檢查。
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>('Hello, Generics');
console.log(output);
枚舉是一種特殊的 "類",用來表示一組固定的常量。
enum Color {
Red,
Green,
Blue
}
let c: Color = Color.Green;
console.log(`Color: ${c}`); // 輸出: 1
TypeScript 支持使用 es 模塊系統進行模塊化開發。
// util.ts
export function print(message: string): void {
console.log(message);
}
// main.ts
import { print } from './util';
print('Hello from modules');
通過使用模塊化,我們可以更好地組織代碼,使其更具可維護性和可讀性。
TypeScript 的類型系統和其他特性使得開發變得更加可靠和高效。通過本教程,應該能夠讓你對 TypeScript 有一個基礎的了解,并通過實例快速上手。
隨著互聯網的快速發展,網絡應用程序的需求也越來越高。為了使網頁更加豐富有趣,許多網站都開始使用套接字(socket)實現網絡的實時通信。而 tcp/ip 協議則常常用于實現此類應用程序。
TCP/IP協議是一種工業標準協議,是互聯網使用最廣泛的協議之一。它提供了一種在不同的計算機之間進行數據傳輸的方式。該協議由兩個協議組成:TCP和IP。其中TCP協議是面向連接的,可以確保數據的可靠傳輸。而IP協議則是面向無連接的,能夠處理計算機之間的網絡路由。
php進行網絡編程的方式有很多,比如比較出名的swoole或者workerman框架。但是這些框架對環境有著一定要求,比如swoole就不能在windwos環境下運行。要么只能在服務器上,或者在docker里面運行。這對于敏捷性開發測試來說,都不希望花大量時間來配置環境。
我們本文介紹的幾種網絡編程,就十分簡單。開箱即用。
ReactPHP是一個用于PHP中事件驅動編程的低級庫。其核心是一個事件循環,在此基礎上提供低級實用程序,如:流抽象、異步DNS解析程序、網絡客戶端/服務器、HTTP客戶端/服務器以及與進程的交互。第三方庫可以使用這些組件來創建異步網絡客戶端/服務器等。
github:
https://github.com/reactphp/reactphp
本文搭建的tcp服務,基于ReactPHP來實現。
本文使用windows環境,使用php 8.0.2composer 2.2.6
{
"require": {
"react/socket": "^v1.15.0"
}
}
require 'vendor/autoload.php';
$loop = React\EventLoop\Loop::get();
//監聽8090端口
$socket = new React\Socket\SocketServer('127.0.0.1:8090', [], $loop);
$socket->on('connection', function ($conn) {
echo "New connection\n";
// 接收數據
$conn->on('data', function ($data) use ($conn) {
echo "Received data: " . $data;
// 將接收到的數據發送回客戶端
$conn->write($data);
});
// 關閉連接處理
$conn->on('close', function () use ($conn) {
echo "Connection closed\n";
});
// 錯誤處理
$conn->on('error', function (\Exception $e) use ($conn) {
echo "Error: " . $e->getMessage() . "\n";
$conn->close();
});
});
$socket->on('error', function (\Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
});
$loop->run();
收到回復,證明tcp服務是通的,可以進行tcp通訊了,可以愉快的開發自己想要的邏輯了。
cboden/ratchet 用于異步服務WebSockets的PHP庫。通過簡單的接口構建應用程序,并通過組合不同的組件在不更改任何代碼的情況下重用應用程序。
github:
https://github.com/ratchetphp/Ratchet
在上面的基礎上,命令行執行以下命令
composer require cboden/ratchet
<?php
/**
* Created by PhpStorm.
* User: MR.Li
* Date: 2024/5/6
* Time: 16:35
*/
require 'vendor/autoload.php';
//websocket
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
class EchoWebSocket implements MessageComponentInterface {
public function onOpen(ConnectionInterface $conn) {
// 新連接時會調用
$conn->send('hello world');
}
public function onMessage(ConnectionInterface $conn, $msg) {
// 收到消息時調用
$conn->send($msg);
}
public function onClose(ConnectionInterface $conn) {
// 連接關閉時調用
}
public function onError(ConnectionInterface $conn, \Exception $e) {
// 發生錯誤時調用
$conn->close();
}
}
$loop = React\EventLoop\Loop::get();
$webSock = new EchoWebSocket();
$server = IoServer::factory(
new HttpServer(
new WsServer($webSock)
),
8090
);
$server->run();
php .\websocket.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Go WebSocket Tutorial</title>
</head>
<body>
<h2>Hello World</h2>
<script>
let socket = new WebSocket("ws://127.0.0.1:8090");
console.log("Attempting Connection...");
socket.onopen = () => {
console.log("Successfully Connected");
//socket.send('Hi From the Client!')
};
socket.onclose = event => {
console.log("Socket Closed Connection: ", event);
//socket.send("Client Closed!")
};
socket.onerror = error => {
console.log("Socket Error: ", error);
};
socket.onmessage = msg => {
console.log("Socket getMsg: ", msg);
};
/* var int=self.setInterval("clock()",3000);*/
/*function clock(){
// console.log('22222222')
socket.send("Hi webcoket")
}*/
</script>
</body>
</html>
利用 react/socket 和 cboden/ratchet兩個包可以實現簡單的 tcp 和 websoket服務搭建,操作簡單,傻瓜式教程。讓新手小白也能用上高大上的網絡編程。不用去安裝各種擴展,和環境。
瓜一詞借鑒自傻瓜相機,又稱輕便相機、全自動相機,通常指容易操作針對一般人而設計的小型全自動相機。
在 HelloGitHub 找到有趣、入門級的開源項目,大家好我是鹵蛋。說到搜索第一個想到的應該是鼎鼎大名的 Elasticsearch,但 ES 對于個人項目有些重。
今天給大家帶來一款輕盈、人人都會用的開源傻瓜搜索引擎——MeiliSearch
在介紹 MeiliSearch 之前,我想先聊下我是怎么找到它并喜歡上它的。
我開發的 HelloGitHub 小程序:支持關鍵字搜索往期月刊中的開源項目。
小程序的搜索功能是用 Rust 寫的開源搜索引擎 Sonic,它雖然搜索速度快但使用過程中發現:
這些問題直接影響了搜索的體驗,讓我十分苦惱一邊看搜索相關的知識,另外也在尋找新的開源解決方案。想找一個:
部署+配置簡單、支持中文分詞、搜索速度快、輕量級開源搜索引擎項目。
俗稱:傻瓜中文搜索引擎。
它有個“美麗”(meili)的名字「MeiliSearch」,同樣是用 Rust 寫的開源搜索引擎,支持:
概述功能:搜索速度快、全文搜索、支持漢字、容易安裝和維護,這不就是我在找的:傻瓜中文搜索引擎嗎?
我已經摩拳擦掌的躍躍欲試了,話不多說搞起!
紙上得來終覺淺,得上手試試效果。
Linux & Mac OS 的一鍵安裝和啟動的命令:
curl -L https://install.meilisearch.com | sh
./meilisearch
這個安裝夠不夠傻瓜 啟動成功如下圖:
用瀏覽器訪問:http://127.0.0.1:7700/ 就可以看到 MeiliSearch 提供的 Web 搜索頁面。我提前寫入了一些數據,用來演示搜索:
MeiliSearch 就是一個搜索的服務,提供 RESTful API 通訊協議更加通用,官方提供了多種編程語言的客戶端:
后面的演示將采用 Python 代碼作為示例,安裝 Python SDK:
# 要求 Python3.6+
pip3/pip install meilisearch
用 Python 實現連接、寫入、查詢、刪除等基本操作:
import meilisearch
client = meilisearch.Client('http://127.0.0.1:7700', 'masterKey') # masterKey 是密碼
# index 相當于數據庫的表
index = client.index('books')
# 準備寫入搜索的數據
documents = [
{ 'book_id': 123, 'title': 'Pride and Prejudice' },
{ 'book_id': 456, 'title': 'Le Petit Prince' },
{ 'book_id': 1, 'title': 'Alice In Wonderland' },
{ 'book_id': 1344, 'title': 'The Hobbit' },
{ 'book_id': 4, 'title': 'Harry Potter and the Half-Blood Prince' },
{ 'book_id': 42, 'title': 'The Hitchhiker\'s Guide to the Galaxy' }
]
# 刪:清空指定 index
index.delete_all_documents()
# 寫:
result = index.add_documents(documents)
# 該引擎會根據寫入數據 ID 做替換或者新增的操作
# 寫入后并不代表搜索引擎處理完成,可以查看返回 updateId 的狀態
index.get_update_status(result.get('updateId'))
# enqueued, processed or failed 三種狀態(processed 代表完成)
# 查:
index.search('harry pottre')
# 結果:
# 包含豐富的字段
"""
{
// 命中的結果
"hits" => [{
"book_id" => 4,
"title" => "Harry Potter and the Half-Blood Prince"
}],
// 頁
"offset" => 0,
// 每頁條數
"limit" => 20,
// 處理耗時
"processingTimeMs" => 1,
// 查詢的內容
"query" => "harry pottre"
}
"""
至此已經實現了搜索的最基本的功能,但探索不止于此。
MeiliSearch 可通過配置規則來提高搜索結果:
可以用 Python 客戶端更新 MeiliSearch 配置,示例代碼:
# 停用詞
client.index('movies').update_settings({
'stopWords': [
'the',
'a',
'an'
],
})
# 排序規則
client.index('movies').update_ranking_rules([
"typo",
"words",
"proximity",
"attribute",
"wordsPosition",
"exactness",
"asc(publish_time)",
"desc(watch)"
])
# 查看 stop words
client.index('movies').get_stop_words()
# 重置設置
# index.reset_settings()
# 除了搜索其它操作都是異步,會直接返回一個 updateId 需要通過 ID 查詢處理狀態
# wait_for_pending_update 可阻塞等待處理結果
這些設置可以有效的提高搜索效果,比如使用停用詞之前,搜索“開源的書籍”命中不了“開源書籍”,加了停用詞即可命中,因為匹配時忽略了輸入內容包含的停用詞(無用詞)。
說一個我遇到的坑,我測試搜索效果時發現:go 搜不到,但是 golang 就可以搜索到,排查了半天最后發現是因為 go 在上面的停用詞字典中
另外,功能上對比 sonic 沒有詞聯想(suggest),可以通過新建 index+searchableAttributes 實現。
同義詞集合我沒有找到,如果大家有現成的 中/英文 同義詞詞典,歡迎留言告訴我~感謝
MeiliSearch 部署很簡單,增加到系統的 systemd 服務就行了。
cat << EOF > /etc/systemd/system/meilisearch.service
[Unit]
Description=MeiliSearch
After=systemd-user-sessions.service
[Service]
Type=simple
ExecStart=/usr/bin/meilisearch --http-addr 127.0.0.1:7700 --env production --master-key xxxxxx
[Install]
WantedBy=default.target
EOF
# Set the service meilisearch
systemctl enable meilisearch
# Start the meilisearch service
systemctl start meilisearch
# Verify that the service is actually running
systemctl status meilisearch
但部署正式環境,需要注意以下幾點:
以上就是我使用 MeiliSearch 的一些心得,總體給我的感覺:
一條命令即可啟動搜索服務,一行代碼實現搜索功能,有了它我這個搜索小白都能分分鐘實現一個搜索服務,舒服~
我用 MeiliSearch 重寫了 HelloGitHub 小程序的搜索功能,后端用的 FastAPI 框架。除此之外還增加了一些新功能:
HelloGitHub 小程序第二版效果圖如下:
后面計劃增加:信息流、評論、打分、用戶系統、積分系統,因為只有我一個人開發,所以進度會很慢...但我不會半途而廢噠
如果說 MeiliSearch 缺點的話,我覺得搜索準確度還有待提高,一方面我需要學習下分詞和 NLP 的一些知識,另一方面需要再熟悉下它的 API 和原理,然后再找一些詞典輔助,應該能提高準確度,但心急吃不了熱豆腐慢慢來吧。
最后,希望本文的分享有幫助到你,今天的文章就到這里了。
優秀的開源項目像散落在海邊的貝殼,需要發現它的人。
HelloGitHub 就是拾貝者,找開源項目來 HelloGitHub 就對了!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。