AI真的可以写出可商用的代码吗?
背景
在MQTT中,代理(Broker)将发布的消息(publish messages)根据它们的主题(topic)匹配到订阅了这些主题的客户端。这个过程对于客户端来说是透明的,因为客户端只需要指定它们感兴趣的主题,而MQTT代理负责将消息分发给所有订阅了匹配主题的客户端。 如果想通过topic作为解耦key,实现一个客户端多个Listener,每个Listener都具备自己的topic及业务处理逻辑(类似RocketMQ消费者模式)。所以MQTT客户端具备把消息根据topic路由到相应的Listener中。 回归主题我希望通过AI帮实现topic路由。(实现matchTopic方法)
private boolean matchTopic(String subscribedTopic, String publishedTopic)
AI写代码
AI选择:通义千问
第一次
指令
通过java实现mqtt的topic路由匹配的方法matchTopic(String subscribedTopic,String publishedTopic)
AI输出(只粘贴代码部分)
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MqttTopicMatcher {
/**
* 模拟MQTT的topic匹配。
*
* 注意:这个实现是简化的,它不支持通配符在主题字符串中的非末尾位置,
* 并且没有处理多层加号(`+`)和井号(`#`)的复杂情况。
* 它主要用于理解和教学目的。
*
* @param subscribedTopic 订阅的主题,可能包含`+`或`#`通配符
* @param publishedTopic 发布的主题
* @return 如果发布的主题与订阅的主题匹配,则返回true;否则返回false
*/
public static boolean matchTopic(String subscribedTopic, String publishedTopic) {
// 将加号(`+`)替换为正则表达式中的任意字符(`.`)
String regexTopic = subscribedTopic.replace("+", ".");
// 处理井号(`#`):如果订阅的主题以`#`结尾,则替换为任意数量的任意字符(`.*`)
// 注意:这里我们假设`#`只出现在字符串的末尾,且前面没有其他通配符
if (regexTopic.endsWith("#")) {
regexTopic = regexTopic.substring(0, regexTopic.length() - 1) + ".*";
}
// 编译正则表达式
Pattern pattern = Pattern.compile("^" + regexTopic + "$");
// 匹配发布的主题
Matcher matcher = pattern.matcher(publishedTopic);
return matcher.matches();
}
public static void main(String[] args) {
// 示例
String subscribedTopic1 = "sensors/+/level";
String publishedTopic1 = "sensors/temperature/level";
System.out.println(matchTopic(subscribedTopic1, publishedTopic1)); // 应输出 true
String subscribedTopic2 = "sensors/#";
String publishedTopic2 = "sensors/temperature/room1/level";
System.out.println(matchTopic(subscribedTopic2, publishedTopic2)); // 应输出 true
String subscribedTopic3 = "sensors/+";
String publishedTopic3 = "sensors/temperature/level";
System.out.println(matchTopic(subscribedTopic3, publishedTopic3)); // 应输出 false,因为`+`只匹配单个层级
// 注意:这个实现是简化的,不涵盖所有MQTT topic匹配的场景
}
}
验证
public static void main(String[] args) {
boolean a = matchTopic("$SYS/brokers/+/clients/#", "$SYS/brokers/emqx@172.51.0.6/clients/mqttx_b2136a2c/connected");
System.out.println("msg: " + a); // 应该输出 true
boolean b = matchTopic("DEVICE/+/msg", "DEVICE/0000000091238112/msg");
System.out.println("msg: " + b); // 应该输出 true
}
public static boolean matchTopic(String subscribedTopic, String publishedTopic) {
// 将加号(`+`)替换为正则表达式中的任意字符(`.`)
String regexTopic = subscribedTopic.replace("+", ".");
// 处理井号(`#`):如果订阅的主题以`#`结尾,则替换为任意数量的任意字符(`.*`)
// 注意:这里我们假设`#`只出现在字符串的末尾,且前面没有其他通配符
if (regexTopic.endsWith("#")) {
regexTopic = regexTopic.substring(0, regexTopic.length() - 1) + ".*";
}
// 编译正则表达式
Pattern pattern = Pattern.compile("^" + regexTopic + "$");
// 匹配发布的主题
Matcher matcher = pattern.matcher(publishedTopic);
return matcher.matches();
}
实质输出结果:
msg: false
msg: false
结论:
不符合
第二次
指令
public static void main(String[] args) {
boolean a = matchTopic("$SYS/brokers/+/clients/#", "$SYS/brokers/emqx@172.51.0.6/clients/mqttx_b2136a2c/connected");
System.out.println("msg: " + a); // 应该输出 true
boolean b = matchTopic("DEVICE/+/msg", "DEVICE/0000000091238112/msg");
System.out.println("msg: " + b); // 应该输出 true
}
public static boolean matchTopic(String subscribedTopic, String publishedTopic) {
// 将加号(`+`)替换为正则表达式中的任意字符(`.`)
String regexTopic = subscribedTopic.replace("+", ".");
// 处理井号(`#`):如果订阅的主题以`#`结尾,则替换为任意数量的任意字符(`.*`)
// 注意:这里我们假设`#`只出现在字符串的末尾,且前面没有其他通配符
if (regexTopic.endsWith("#")) {
regexTopic = regexTopic.substring(0, regexTopic.length() - 1) + ".*";
}
// 编译正则表达式
Pattern pattern = Pattern.compile("^" + regexTopic + "$");
// 匹配发布的主题
Matcher matcher = pattern.matcher(publishedTopic);
return matcher.matches();
}
实质输出结果:
msg: false
msg: false
AI输出(只粘贴代码部分)
您提供的代码中,matchTopic
方法用于将MQTT主题过滤器subscribedTopic
转换为正则表达式,并检查发布的主题publishedTopic
是否与该正则表达式匹配。但是,这里有几个需要注意的点:
正则表达式边界:
在 MQTT 主题匹配中,通常期望整个主题字符串与过滤器完全匹配(或至少从开头开始匹配,直到过滤器的末尾)。然而,find()
方法在Matcher
类中用于查找与正则表达式匹配的任何子序列,而不是整个字符串。因此,如果publishedTopic
包含比subscribedTopic
更长的前缀,find()
仍然会返回true,即使后续部分不匹配。 完整的字符串匹配:
为了确保整个publishedTopic
字符串与subscribedTopic
匹配(或匹配到subscribedTopic
指定的模式),您应该在正则表达式的前后添加^
和$
锚点。 处理$
前缀:
在MQTT中,$SYS
是一个保留前缀,用于系统主题。在正则表达式中,$
是一个特殊字符,表示字符串的末尾。但是,由于MQTT主题中的$
仅仅是文本的一部分,您不需要在正则表达式中对它进行特殊处理(除非您打算在正则表达式中直接使用$
的特殊含义)。
下面是修改后的matchTopic
方法,它使用matches()
,并确保整个字符串匹配:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static boolean matchTopic(String subscribedTopic, String publishedTopic) {
// 将 + 替换为 [^/]+,将 # 替换为 .*,并在字符串前后添加 ^ 和 $ 以确保整个字符串匹配
String regexTopic = "^" + subscribedTopic.replace("+", "[^/]+").replace("#", ".*") + "$";
Pattern pattern = Pattern.compile(regexTopic);
Matcher matcher = pattern.matcher(publishedTopic);
return matcher.matches(); // 使用 matches() 来确保整个字符串匹配
}
public static void main(String[] args) {
boolean a = matchTopic("$SYS/brokers/+/clients/#", "$SYS/brokers/emqx@172.51.0.6/clients/mqttx_b2136a2c/connected");
System.out.println("msg: " + a); // 应该输出 true
boolean b = matchTopic("DEVICE/+/msg", "DEVICE/0000000091238112/msg");
System.out.println("msg: " + b); // 应该输出 true
}
验证
实质输出结果:
msg: false msg: true
结论:
不符合
第三次
指令
结果还是msg: false
AI输出(只粘贴代码部分)
在从你提供的代码来看,问题可能在于正则表达式的构建方式。+
和#
通配符需要正确地转换为正则表达式来匹配MQTT主题。+
代表单个层级中的任意非斜杠字符。#
代表从层级的某一点开始到主题结尾的所有层级。
你的代码中已经正确地处理了+
和#
,但可能存在一些细微的问题导致输出结果为false
。
让我们稍微调整一下你的代码,以确保它能够正确地处理MQTT主题的匹配:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static boolean matchTopic(String subscribedTopic, String publishedTopic) {
// 将 MQTT 通配符转换为正则表达式
String regexTopic = "^" + subscribedTopic.replace("+", "[^/]+").replace("#", "([^/]+)/.*") + "$";
// 编译正则表达式
Pattern pattern = Pattern.compile(regexTopic);
// 创建匹配器并检查是否匹配
Matcher matcher = pattern.matcher(publishedTopic);
return matcher.matches(); // 使用 matches() 来确保整个字符串匹配
}
public static void main(String[] args) {
boolean a = matchTopic("$SYS/brokers/+/clients/#", "$SYS/brokers/emqx@172.51.0.6/clients/mqttx_b2136a2c/connected");
System.out.println("msg: " + a); // 应该输出 true
boolean b = matchTopic("DEVICE/+/msg", "DEVICE/0000000091238112/msg");
System.out.println("msg: " + b); // 应该输出 true
}
在上述代码中,我将#
的替换部分稍作修改。原来的".*"
可能会匹配任何字符(包括斜杠),这可能会导致意外匹配。通过使用"([^/]+)/.*"
,我们确保了 # 之前的部分必须是一个不包含斜杠的字符串,并且之后可以跟任何东西(包括零个或多个层级)。
让我们尝试运行这段修改后的代码。如果你仍然遇到问题,请告诉我,我们可以进一步调试。
验证
实质输出结果:
msg: false msg: true
结论:
不符合
第四次
指令
运行结果还是不对,$SYS/brokers/emqx@172.51.0.6/clients/mqttx_b2136a2c/connected
,输出结果还是msg: false
AI输出(只粘贴代码部分)
在既然正则表达式看起来是正确的,但仍然没有匹配成功,我们需要进一步检查正则表达式的实现细节。问题可能在于正则表达式如何处理#
之后的内容。 在MQTT中,#
代表从层级的某一点开始到主题结尾的所有层级。这意味着#
之前的部分必须是一个完整的层级,而#
之后的部分可以是零个或多个层级。 让我们再次修改正则表达式以确保这一点得到正确的处理:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static boolean matchTopic(String subscribedTopic, String publishedTopic) {
// 将 MQTT 通配符转换为正则表达式
String regexTopic = "^" + subscribedTopic
.replace("+", "[^/]+")
.replace("#", "([^/]+)(/.*)?")
+ "$";
System.out.println("Regex topic: " + regexTopic); // 添加这一行以查看正则表达式
// 编译正则表达式
Pattern pattern = Pattern.compile(regexTopic);
// 创建匹配器并检查是否匹配
Matcher matcher = pattern.matcher(publishedTopic);
return matcher.matches(); // 使用 matches() 来确保整个字符串匹配
}
public static void main(String[] args) {
boolean a = matchTopic("$SYS/brokers/+/clients/#", "$SYS/brokers/emqx@172.51.0.6/clients/mqttx_b2136a2c/connected");
System.out.println("msg: " + a); // 应该输出 true
boolean b = matchTopic("DEVICE/+/msg", "DEVICE/0000000091238112/msg");
System.out.println("msg: " + b); // 应该输出 true
}
这里的关键变化是在#
的替换部分:"([^/]+)(/.*)?"
:这部分正则表达式意味着#
前面的部分必须是一个不包含斜杠的字符串,而#
后面的部分可以是零个或多个层级。"(.*)" / "(/.*)"
都用来匹配剩余的路径,但(/.*)?
表示这个部分是可选的,即#
后面可以没有更多的层级。
现在,让我们再次运行这段代码。你应该能看到输出的正则表达式,以及最终的匹配结果。如果还是有问题,请提供输出结果以便进一步分析。
验证
实质输出结果:
msg: false msg: true
结论:
不符合
第五次
指令
运行结果还是不对,$SYS/brokers/emqx@172.51.0.6/clients/mqttx_b2136a2c/connected
,怀疑$SYS
影响了正则匹配,输出结果还是msg: false
AI输出(只粘贴代码部分)
你提到$SYS
可能影响了正则表达式的匹配。确实,在正则表达式中,某些特殊字符会被解释为具有特殊的含义,而非直接的文本匹配。在这种情况下,$
是一个特殊字符,在正则表达式中通常用于表示字符串的结尾。因此,我们需要对$SYS
进行转义,以确保它被视为普通文本而不是特殊符号。
让我们修改代码以转义$SYS
字符串中的$
,确保它被视为普通的字符。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static boolean matchTopic(String subscribedTopic, String publishedTopic) {
// 将 MQTT 通配符转换为正则表达式
String regexTopic = "^" + subscribedTopic
.replace("+", "[^/]+")
.replace("#", "([^/]+)/.*")
.replace("$", "\$") // 转义 $ 字符
+ "$";
// 编译正则表达式
Pattern pattern = Pattern.compile(regexTopic);
// 创建匹配器并检查是否匹配
Matcher matcher = pattern.matcher(publishedTopic);
return matcher.matches(); // 使用 matches() 来确保整个字符串匹配
}
public static void main(String[] args) {
boolean a = matchTopic("$SYS/brokers/+/clients/#", "$SYS/brokers/emqx@172.51.0.6/clients/mqttx_b2136a2c/connected");
System.out.println("msg: " + a); // 应该输出 true
boolean b = matchTopic("DEVICE/+/msg", "DEVICE/0000000091238112/msg");
System.out.println("msg: " + b); // 应该输出 true
}
在这个版本中,我们添加了一个.replace("$", "\$")
来转义$SYS
中的$
字符。这将确保$SYS
在正则表达式中被视为普通文本。
现在,让我们再次运行这段代码。你应该能看到输出的正则表达式,以及最终的匹配结果。如果还是有问题,请提供输出结果以便进一步分析。
验证
实质输出结果:
msg: true msg: true
结论:
符合
代码最终结果:
对代码今天细微调整,运营到生产环境代码。
private boolean matchTopic(String subscribedTopic, String publishedTopic) {
String regexTopic = "^" + subscribedTopic.replace("+", "[^/]+").replace("#", "([^/]+)/.*").replace("$", "\$") + "$";
// 编译正则表达式
Pattern pattern = Pattern.compile(regexTopic);
// 创建匹配器并检查是否匹配
Matcher matcher = pattern.matcher(publishedTopic);
return matcher.matches(); // 使用 matches() 来确保整个字符串匹配
}
总结
在使用AI工具进行代码生成时,用户可以通过简单的自然语言描述或问题,AI便能快速理解并生成相应的代码片段。这种交互方式非常直观,用户只需提供关键信息和问题,AI便能迅速响应并生成匹配的代码。 AI写代码的体验还体现在其高效性和便捷性上。通过AI的帮助,开发者可以更加专注于项目的核心逻辑和功能实现,而无需在编写基础代码上花费过多时间。这不仅能够提高开发效率,还能在一定程度上减轻开发者的负担,特别是在面对复杂或重复性的编程任务时,AI工具能够显著提升工作效率。 尽管AI工具在代码生成方面展现出了强大的能力,但开发者在使用时仍需保持警惕,确保生成的代码符合项目的实际需求和标准。此外,对于特定领域的复杂应用或特定需求的实现,人类开发者的专业知识和经验仍然是不可或缺的。因此,AI工具与人类开发者的结合将是未来软件开发的一个重要趋势,共同推动软件开发的进步和创新。
来源:juejin.cn/post/7397668641645396022