{"id":696067,"date":"2026-04-02T14:34:24","date_gmt":"2026-04-02T13:34:24","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=go&#038;p=696067"},"modified":"2026-04-02T14:43:46","modified_gmt":"2026-04-02T13:43:46","slug":"code-like-a-pirate-with-junie-and-goland","status":"publish","type":"go","link":"https:\/\/blog.jetbrains.com\/zh-hans\/go\/2026\/04\/02\/code-like-a-pirate-with-junie-and-goland","title":{"rendered":"Code like a PIRATE with Junie and GoLand"},"content":{"rendered":"\n<p><em>This is a guest post from John Arundel, a Go writer and teacher who runs a <\/em><a href=\"https:\/\/bitfieldconsulting.com\/subscribe\" target=\"_blank\" rel=\"noopener\"><em>free email course for Go learners<\/em><\/a><em>. His most recent book is <\/em><a href=\"https:\/\/bitfieldconsulting.com\/books\/deeper\" target=\"_blank\" rel=\"noopener\"><em>The Deeper Love of Go<\/em><\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Ahoy, maties! Cap\u2019n Long John Arundel here with more tips on sailing the good ship <a href=\"https:\/\/www.jetbrains.com\/go\/\" data-type=\"link\" data-id=\"https:\/\/www.jetbrains.com\/go\/\" target=\"_blank\" rel=\"noopener\">GoLand<\/a>. This time, we\u2019ll lay aloft to the crow\u2019s nest and turn our spyglass on <a href=\"https:\/\/www.jetbrains.com\/junie\/\" target=\"_blank\" rel=\"noopener\">Junie<\/a>, the JetBrains AI coding agent.<\/p>\n\n\n\n<p>If you\u2019re new to Junie and AI tools, and aren\u2019t sure where to start, think of this as your treasure map to <a href=\"https:\/\/blog.jetbrains.com\/go\/2025\/09\/08\/goland-can-do-that-ten-secret-superpowers-you-might-not-know\/\">the hidden gold of GoLand productivity<\/a>. Arrr you ready to start coding like a pirate?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Flying the black flag<\/strong><\/h2>\n\n\n\n<p>Your first voyage with AI development tools can be a perilous one, veering from calm seas of code to storms of syntax errors and test failures. So, will your <a href=\"https:\/\/junie.jetbrains.com\/\" target=\"_blank\" rel=\"noopener\">AI agent<\/a> be a trusty first mate, or just an unpredictable <a href=\"https:\/\/en.wikipedia.org\/wiki\/Stochastic_parrot\" target=\"_blank\" rel=\"noopener\">stochastic parrot<\/a> squawking nonsense from your shoulder?<\/p>\n\n\n\n<p>Junie is pretty smart, and she can tackle any task you choose, but she needs the guidance of a good cap\u2019n.&nbsp;To help you stay on course, I\u2019ve put together a handy six-step workflow I like to call \u201cCode like a PIRATE\u201d. Aye, \u2018tis another o\u2019 my <a href=\"https:\/\/bitfieldconsulting.com\/posts\/crisp-code\" target=\"_blank\" rel=\"noopener\">made-up acronyms<\/a>\u2014but ye\u2019ll find it easy to remember, me hearties [<em>Are we doing the pirate thing for the whole article?\u2014Anna<\/em>]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u201cP\u201d is for Plan<\/strong><\/h2>\n\n\n\n<p>Every good voyage begins with a map. When you set Junie a task, tell her where the ship\u2019s headed, so she\u2019ll know which direction to steer. (I\u2019m sure Junie won\u2019t mind me calling her \u201cshe\u201d; fun fact, lots of pirates were women\u2014including <a href=\"https:\/\/en.wikipedia.org\/wiki\/Women_in_piracy\" target=\"_blank\" rel=\"noopener\">quite a few of the men<\/a>).<\/p>\n\n\n\n<p>Ask Junie to draw up a quick chart for the voyage, but not to set sail until you\u2019ve approved it:<\/p>\n\n\n\n<p><em>Arr, Junie, me fine lass. I\u2019m a swashbuckling pirate cap\u2019n who needs a Go program to help me share out the booty from my latest captured Spanish galleon. Don\u2019t code anything yet, but show me a brief plan of how the tool might work.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"2464\" height=\"1378\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/04\/john_arundel_p_for_plan.png\" alt=\"\" class=\"wp-image-696222\"\/><\/figure>\n\n\n\n<p>It\u2019s important to get this stuff right before you even leave the dock, so don\u2019t be afeared to spend a bit of time refining the plan. [<em>I\u2019m \u201cafeared\u201d we might be wearing out the salty sea-dog bit already\u2014Anna<\/em>]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u201cI\u201d is for Iterate<\/strong><\/h2>\n\n\n\n<p>Even the boldest captains don\u2019t try to cross an ocean in a single leap. It\u2019s more effective to island-hop, sailing a short distance at a time and checking you\u2019re still on course. Give Junie one small task at a time, starting with the simplest possible program that could be useful:<\/p>\n\n\n\n<p><em>Let\u2019s start with a really simple prototype. I\u2019d like to be able to run the \u2018booty\u2019 calculator and answer two questions: the number of crew, and the number of pieces of eight to be divided among them.<\/em><\/p>\n\n\n\n<p><em>Assume everyone has an equal share. The tool should print out how much each crew member is due. Write just enough code to achieve this, and then we\u2019ll think about the next stage.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"2464\" height=\"1456\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/04\/john_arundel_i_for_iterate.png\" alt=\"\" class=\"wp-image-696211\"\/><\/figure>\n\n\n\n<p>With too vague a heading, Junie can end up going a bit adrift, like any of us: don\u2019t hesitate to cry \u201cAvast heaving there!\u201d and interrupt her if that happens. Rowing back when the project has gone too far in the wrong direction will cost you a lot of time and doubloons [<em>Seriously, clap a stopper on the pirate speak for now\u2014Anna<\/em>]. Sorry, I meant to say \u201ctokens\u201d.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u201cR\u201d is for Review<\/strong><\/h2>\n\n\n\n<p>Once Junie has completed each iteration, go through the code line by line to check and review her work. She\u2019s pretty good at delivering <em>what<\/em> you asked for, but she doesn\u2019t necessarily know <em>how<\/em> you want it. For example:<\/p>\n\n\n\n<p><em>Nice job, Junie, but I have a few suggestions for improvement.<\/em><\/p>\n\n\n\n<ol>\n<li><em>Instead of creating a <code>bufio.Scanner<\/code> in main and passing a pointer to it into the <code>askInt<\/code> function, let\u2019s eliminate some of that paperwork. Change <code>askInt<\/code> to take just the prompt string, and have it create the scanner internally.<\/em><\/li>\n\n\n\n<li><em>The <code>askInt<\/code> function shouldn\u2019t print error messages and call <code>os.Exit<\/code> if there\u2019s a scan error. Instead, have it return any error along with the integer result. Let main take care of all the printing and exiting.<\/em><\/li>\n\n\n\n<li><em>If there\u2019s an error from <code>strconv.Atoi<\/code>, include the invalid input in the error message. For example, \u201cSorry, I didn\u2019t understand <code>%q<\/code>. Please enter a whole number.\u201d<\/em><\/li>\n\n\n\n<li><em>Move the shares calculation into its own function, so that we decouple the input\/output code from the business logic. Have it return the share and remainder values, so that main can print them out.<\/em><\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"2464\" height=\"1456\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/04\/john_arundel_r_for_review.png\" alt=\"\" class=\"wp-image-696233\"\/><\/figure>\n\n\n\n<p>When giving feedback, bundle all your comments together in one message. This lets Junie generate the new version of the program in a single step, saving tokens. If you keep making small comments and asking her to rebuild the whole program each time, you\u2019ll find your pieces of eight\u2014I mean, credits\u2014dwindling rapidly.<\/p>\n\n\n\n<p>Good programs have a harmonious architecture that makes overall sense: everything works the same way everywhere and it all seems to fit together neatly. Junie can\u2019t achieve this without your guidance, so keep a hand on the tiller and help her ensure things slot neatly into a unified structure.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u201cA\u201d is for Assess<\/strong><\/h2>\n\n\n\n<p>Once Junie has finished the step you asked for, don\u2019t just glance at the code and move on\u2014take a moment to assess whether it actually does what it should. Does the program run cleanly? Do the functions behave as expected? Are there strange side effects lurking in the bilges, waiting to sink your ship later? [<em>What did I <\/em><strong><em>just<\/em><\/strong><em> say?\u2014Anna<\/em>]<\/p>\n\n\n\n<p>Now that you can see the program in action, you might realise it\u2019s not quite what you want. If so, now\u2019s the time to adjust course, either with Junie\u2019s help or by making little steering inputs yourself.<\/p>\n\n\n\n<p>If you\u2019re happy with the assessment, though, you can move on to the next iterative step towards the final program:<\/p>\n\n\n\n<p><em>Shiver me timbers, Junie, that be some fine work.<\/em><\/p>\n\n\n\n<p><em>Could you now please move the business logic functions into a booty package in the project root, and put the main.go file into a cmd\/booty subfolder?<\/em><\/p>\n\n\n\n<p><em>Also, could ye change the plunder calculations so that the captain gets twice the share of a regular crewmember? Print out the captain\u2019s share separately.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"945\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/04\/john_arundel_a_for_assess.png\" alt=\"\" class=\"wp-image-696200\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u201cT\u201d is for Test<\/strong><\/h2>\n\n\n\n<p>No old salt trusts a ship that hasn\u2019t been through its sea-trials, and nor should you. As you and Junie build the program, check each new plank is watertight by adding tests to accompany each function. That way, you\u2019ll know as soon as something springs a leak.<\/p>\n\n\n\n<p><em>Arr, please add some unit tests now for the CalculateShares function. Generate at least ten test cases.<\/em><\/p>\n\n\n\n<p><em>Move the askInt function into the booty package too, and add logic to check that the number entered is always 1 or greater, or return an appropriate error if it\u2019s not.<\/em><\/p>\n\n\n\n<p><em>Have the function take an <code>io.Reader <\/code>to read input from, and an <code>io.Writer<\/code> to print prompts to.<\/em><\/p>\n\n\n\n<p><em>Generate two tests for this function, one for valid inputs, one for invalid inputs.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"2464\" height=\"1456\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/04\/john_arundel_t_for_test.png\" alt=\"\" class=\"wp-image-696255\"\/><\/figure>\n\n\n\n<p>Junie can be a helpful shipmate when it comes to drafting tests, but don\u2019t just accept her handiwork blindly. Ask yourself: What is this really testing? Are there hidden reefs\u2014edge cases\u2014that we\u2019re missing? And, when the tests fail (they\u2019re no use otherwise) do they print something helpful?<\/p>\n\n\n\n<p><em>Tis a fine set of tests ye have there, Junie. Could you make them all run in parallel?<\/em><\/p>\n\n\n\n<p><em>In the table tests, could you use a map of test cases keyed by name, and then use t.Run in the test loop with the map key as the subtest name? That\u2019ll make it easier on any scurvy dogs trying to understand the failure output.<\/em><\/p>\n\n\n\n<p><em>Don\u2019t try to inspect the error string itself for invalid inputs; that leads to fragile tests. Instead, just check that AskInt returns any non-nil error for these cases.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"2464\" height=\"1456\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/04\/john_arundel_t_for_test_01.png\" alt=\"\" class=\"wp-image-696244\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u201cE\u201d is for Evaluate<\/strong><\/h2>\n\n\n\n<p>Machine learning is fine, but <em>human<\/em> learning is even better. After each task, take a little time to analyse what worked, and what could have gone better.<\/p>\n\n\n\n<p>Were your prompts detailed enough? Did Junie sail safely into harbour, or did she end up grounded on a sandbar because her pilot was too busy splicing the mainbrace? Every voyage is a lesson that\u2019ll help you sharpen your prompting skills, anticipate pitfalls, and become a steadier pirate cap\u2019n for the next expedition.<\/p>\n\n\n\n<p>If you remember the chart we\u2019ve drawn here and use it to navigate your next project, with the help of Junie and <a href=\"https:\/\/www.jetbrains.com\/go\/download\/\" target=\"_blank\" rel=\"noopener\">GoLand<\/a>, you\u2019ll be ready to truly code like a PIRATE [<em>That\u2019s it, you\u2019re walking the plank\u2014Anna<\/em>].<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Anchors aweigh<\/strong><\/h2>\n\n\n\n<p>Check out the <a href=\"https:\/\/github.com\/bitfield\/booty\" target=\"_blank\" rel=\"noopener\">booty calculator project<\/a> to see what Junie and I built together\u2014try using it to divvy up your own pirate booty with friends. It\u2019s also kind of fun to say \u201cbooty\u201d.<\/p>\n\n\n\n<p>Until next time, shipmates, wishin\u2019 ye fair winds and full sails!<\/p>\n\n\n\n<p><strong>Legal disclaimer:<\/strong> <em>JetBrains s.r.o. does not advocate piracy, illegal seizure of vessels on the high seas, or the consumption of rum. Please swashbuckle responsibly.<\/em><\/p>\n","protected":false},"author":1386,"featured_media":696148,"comment_status":"closed","ping_status":"closed","template":"","categories":[8899,4221],"tags":[8724,8759,6947],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/go\/696067"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/go"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/types\/go"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/users\/1386"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/comments?post=696067"}],"version-history":[{"count":9,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/go\/696067\/revisions"}],"predecessor-version":[{"id":706806,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/go\/696067\/revisions\/706806"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media\/696148"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media?parent=696067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/categories?post=696067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/tags?post=696067"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/cross-post-tag?post=696067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}