讓 AI 為你寫代碼 – 體驗 Github Copilot
前幾天在群里看到有大神分享 Copoilot AI 寫代碼,看了幾個截圖有點不敢相信自己的眼睛。今天趕緊自己也來體驗一下 Copoilot AI 寫代碼到底有多神奇。
申請
現在 Copoilot 還處在預覽階段,想要體驗需要先申請。等待大概一晚會收到郵件提示申請試用成功,然後就可以安裝 copilot 的插件進行體驗了。
申請的地址為 //copilot.github.com/ 。
安裝插件
打開 VSCode 的擴展面板,搜 copilot 找到插件點擊安裝。
安裝完成後會提示你需要登錄 github 進行授權。這一步在國內可能會校驗失敗,多嘗試幾次就會成功。
開始體驗
安裝完插件後就可以開始體驗了。使用其實來也非常簡單,你只需要寫下注釋比如 // 比較兩個數的大小 ,然後回車,稍等一會就 copilot 就會把建議代碼給列出來。或者直接寫下方法名,比如 function compareDate () { 寫下第一個 { 的時候按下回車,稍等一會 copilot 就會給出建議代碼,按一次 tab 就會生成代碼。
copilot 可能會給出多種建議的代碼,使用 alt + [ 或者 alt + ] 可以進行切換。
下面讓我們來測試一下 copilot 生成的代碼到底怎麼樣。
測試JavaScript
新建一個名為 copilottest.js 的文件。
先來一個簡單的,實現一個快速排序,這種標準的算法生成起來應該沒啥難度。直接 // 快排 回車就生成出來了,看了下代碼,還不錯哈。
//快排
function quickSort(arr, left, right) {
if (left < right) {
var pivotIndex = partition(arr, left, right);
quickSort(arr, left, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, right);
}
}
再來一個比較常用的字符串轉時間,並且順便生成一個測試方法。
//把格式為"yyyy-MM-dd"的字符串轉換為Date類型
function stringToDate(str) {
var date = eval('new Date(' + str.replace(/\d+(?=-[^-]+$)/,
function (a) { return parseInt(a, 10) - 1; }).match(/\d+/g) + ')');
return date;
}
//測試 stringToDate 方法是否正確
function testStringToDate() {
var str = "2017-01-01";
var date = stringToDate(str);
alert(date);
}
再來帶判斷邏輯的:比較兩個數字,如果第一個數字大於第二個數字,則返回「微信」否則返回”qq”。
這個考驗一下 copilot 對中文的理解。
//比較兩個數字,如果第一個數字大於第二個數字,則返回「微信」否則返回「qq
function compare(num1, num2) {
if (num1 > num2) {
return "微信";
} else {
return "qq";
}
}
再來一個判斷時間是星期幾的函數
//根據時間判斷星期幾
function getWeek(date) {
var week;
switch (date.getDay()) {
case 0:
week = "星期日";
break;
case 1:
week = "星期一";
break;
case 2:
week = "星期二";
break;
case 3:
week = "星期三";
break;
case 4:
week = "星期四";
break;
case 5:
week = "星期五";
break;
case 6:
week = "星期六";
break;
}
return week;
}
再來試試 http 請求寫的怎麼樣,訪問一下百度把html返回。
//返回baidu.com的html
function getBaiduHtml() {
var url = "//www.baidu.com";
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.send();
var html = xhr.responseText;
return html;
}
JavaScript 操作 html 也很常見,那麼試試查找元素怎麼樣
//查找頁面上所有的div
function findAllDiv() {
var divs = document.getElementsByTagName("div");
return divs;
}
//查找所有頁面上class=user的input元素
function findAllUserInput() {
var inputs = document.getElementsByClassName("user");
return inputs;
}
再來試試 http 提交對象怎麼樣
//請求一個url,post一個json對象
function postJson(url, json) {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, false);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(json));
var response = xhr.responseText;
return response;
}
來個有點難度的,爬取博客園首頁的文章的標題
//爬取cnblogs.com所有文章的標題
function getAllArticleTitle() {
var url = "//www.cnblogs.com/";
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.send();
var html = xhr.responseText;
var reg = /<a href="(.*?)" target="_blank">(.*?)<\/a>/g;
var result = html.match(reg);
return result;
}
測試一下使用某個類庫來完成一些操作
// 使用hls.js播放視頻
function playVideo(video) {
var hls = new Hls();
hls.loadSource("//www.w3school.com.cn/i/movie.mp4");
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function () {
video.play();
});
}
看到這裡有沒有被震驚到?以上代碼全部是 copilot 自動生成的,我僅僅是寫下了幾行注釋。可以看到注釋其實寫的也很簡單,copilot 生成的代碼基本上都符合注釋的內容,可以說 copilot 對中文注釋的理解非常到位。如果你的注釋寫的更加詳細,那麼代碼就會更加符合你的要求。
測試.NET C#
讓我們在來試試 C# 代碼的提示功能怎麼樣。新建一個文件名為 copilottest.cs 的文件。
先來一個簡單的,比較兩個時間的大小。
//比較兩個時間的大小
public static bool CompareTime(string time1, string time2) {
DateTime dt1 = DateTime.Parse(time1);
DateTime dt2 = DateTime.Parse(time2);
if (dt1 > dt2) {
return true;
} else {
return false;
}
}
做為 CRUD boy 自然要測試下數據庫操作。
先來試試使用EF來查找用戶
//使用EF查詢用戶
public static List<User> GetUserList() {
using (var db = new CopiloteContext()) {
return db.User.ToList();
}
}
再來試試使用 dapper 的寫法
//使用dapper查詢用戶
public static List<User> GetUserListDapper() {
using (IDbConnection db = new SqlConnection("server=.;database=copilote;uid=sa;pwd=123456")) {
return db.Query<User>("select * from user").ToList();
}
}
讓我們加大難度,來個連接跟分組統計人數
//查詢2020年每個班級學生的人數
public static void GetClassStudentCount() {
using (IDbConnection db = new SqlConnection("server=.;database=copilote;uid=sa;pwd=123456")) {
db.Query<ClassStudentCount>("select class.name as classname,count(student.id) as studentcount from student left join class on student.classid=class.id where class.year=2020 group by class.name").ToList();
}
}
讓它自動生成改刪查操作
class student {
public int id { get; set; }
public string name { get; set; }
public int classid { get; set; }
}
//student的新增操作
public static void AddStudent(student s) {
using (IDbConnection db = new SqlConnection("server=.;database=copilote;uid=sa;pwd=123456")) {
db.Execute("insert into student(name,classid) values(@name,@classid)", s);
}
}
//student的更新操作
public static void UpdateStudent(student s) {
using (IDbConnection db = new SqlConnection("server=.;database=copilote;uid=sa;pwd=123456")) {
db.Execute("update student set name=@name,classid=@classid where id=@id", s);
}
}
//student的刪除操作
public static void DeleteStudent(int id) {
using (IDbConnection db = new SqlConnection("server=.;database=copilote;uid=sa;pwd=123456")) {
db.Execute("delete from student where id=@id", new { id = id });
}
}
再來試試生成 ASP.NET MVC 的 action 方法。
class UserController : Controller {
//從 request 獲取 name 參數查詢用戶,如果查到就返回否則返回狀態404
public ActionResult GetUser(string name) {
User user = UserService.GetUser(name);
if (user != null) {
return Json(user);
} else {
return HttpNotFound();
}
}
//使用[FromBody]映射成user對象,並保存到數據庫
public ActionResult AddUser([FromBody]User user) {
UserService.AddUser(user);
return Json(user);
}
}
其實我還試驗了一下 JAVA 的代碼,也是毫無壓力,這裡就不貼出來了。
總結
到這裡我已經有點無話可說了。 copilot 深深的震撼了我,感覺 copilot 對注釋的理解根據人類無差別,生成的代碼基本是符合要求的,即使有一點問題那也是因為沒有上下文的原因, copilot 只能生成最常用的語句。copilot 雖然只是生成一個個短小的函數,但是再複雜的系統不都是由無數個簡單的函數組成的嗎?況且 copilot 還只是預覽版,如果再迭代幾個版本,AI 再訓練幾年那麼是不是可以有無限可能。到這裡心裏略有一點憂傷,以後一些低級代碼工作很可能被 AI 代替,程序員的入門門檻進一步降低,這到底是好事還是壞事呢?